Compare commits

..

83 Commits

Author SHA1 Message Date
Twentysix 974aa71759 Added warning 2016-02-17 23:52:21 +01:00
Twentysix c1372806e8 Update README.md 2016-02-17 23:29:57 +01:00
Twentysix 35ed817203 Update README.md 2016-02-11 09:47:05 +01:00
Twentysix 5e431b52bf Added !lmgtfy
!lmgtfy [search terms]
2016-01-26 23:45:00 +01:00
Twentysix 0827fb0c33 Update README.md 2016-01-26 15:12:34 +01:00
Twentysix b5f240fdb8 Hotfix 2016-01-25 22:31:58 +01:00
Twentysix 970c3a5ef0 Custom prefix, can now change settings on the fly
!setting [setting] [value]
2016-01-25 21:49:25 +01:00
Twentysix ef05727477 Prevent URL in !twitchalert 2016-01-23 05:00:49 +01:00
Twentysix e207f09f40 Update README.md 2016-01-22 13:42:17 +01:00
Twentysix c36db5dad1 Typos 2016-01-21 15:44:14 +01:00
Twentysix d06345dbe2 fix !imdb 2016-01-21 15:25:38 +01:00
Twentysix 1763c76d69 Various fixes 2016-01-21 15:08:35 +01:00
Twentysix 45e5886282 !imdb now available 2016-01-21 14:48:28 +01:00
Twentysix d593c9d625 Fixed conflicts 2016-01-21 14:33:18 +01:00
Twentysix 0862681078 Have to fix some stuff before making !imdb available 2016-01-21 14:03:17 +01:00
Twentysix 7cef720350 Merge pull request #28 from WingsOfAltair/patch-1
Added !imdb command
2016-01-21 13:59:00 +01:00
WingsOfAltair eb1b997fa6 Added imdb command
This command provides information about a certain movie using IMDB's API.
Usage example: !imdb The dark knight
2016-01-21 13:51:10 +02:00
Markus 2342016314 Removed !chat
Not yet compatible with async / aiohttp
2016-01-21 12:38:26 +01:00
Markus d654bd9538 Fixed !meme help
Deleted some IDs + Text because the 2000 character limit
2016-01-20 15:34:41 +01:00
Markus dd223a1a1d remove cache file 2016-01-20 13:14:24 +01:00
Markus 44508e1492 Update Reade.md 2016-01-20 13:02:42 +01:00
Markus 15932f3e51 Master Update
General Update
2016-01-20 13:01:19 +01:00
Twentysix 7be20e127b Update README.md 2016-01-18 04:10:46 +01:00
Twentysix 9ce74b6ec8 Poll system, 2 new trivia lists
!poll
!endpoll
2016-01-18 01:57:16 +01:00
Twentysix c0f24ae663 Typo in games trivia list 2016-01-17 05:43:43 +01:00
Markus b8e7e97efe Youtube video title
Now with the title and not more with the id
2016-01-16 23:36:36 +01:00
Markus a48d4e9374 Youtube video title
Now the bot prints the video title and not more the youtube id
2016-01-16 23:27:47 +01:00
Markus c3f7c8936e !chat fix
Fixed a stupid mistake
2016-01-16 18:19:50 +01:00
Markus c1d73c3038 New command [!chat]
Now it's possible to chat with the cleverbot
2016-01-16 18:09:36 +01:00
Twentysix f4fd244554 Update README.md 2016-01-16 03:20:11 +01:00
Twentysix 76068f2393 Added blacklist
!blacklist
!forgive
2016-01-16 01:13:17 +01:00
Twentysix 9943d8472b Proper permission check for voice 2016-01-16 00:13:40 +01:00
Twentysix a4c001dd39 discord.py got fixed, changing again
Message history no longer reversed
2016-01-15 22:03:58 +01:00
Twentysix c45acb65ca Added warning 2016-01-15 21:21:43 +01:00
Twentysix e73e1f38d2 Fix for recent discord.py change 2016-01-15 21:13:58 +01:00
Twentysix aaae7fbfe0 Fix for random encoding issue. Maybe. 2016-01-15 08:49:33 +01:00
Twentysix 2a073bbd50 !urban async friendly 2016-01-14 23:08:43 +01:00
Twentysix 33f5114666 Merge pull request #19 from crysis909/master
!urban - Urban dictionary search
2016-01-14 23:03:24 +01:00
Twentysix f494bac4d9 Hotfix for !song 2016-01-14 17:14:25 +01:00
Twentysix 9830e1d8c3 Phasing out requests module 2016-01-14 17:00:53 +01:00
Twentysix 1dc8f937f5 Update README.md 2016-01-14 12:42:54 +01:00
Twentysix 95313ae446 New trivia list, anime 2016-01-13 13:20:26 +01:00
Twentysix 706b4e63a2 Update README.md 2016-01-12 23:16:25 +01:00
Twentysix 1162df4157 Settings and empty files generated at runtime
Settings and empty files are now generated at runtime
Easier first run process, the user can input email, password and admin
role directly into the terminal
2016-01-12 22:08:06 +01:00
Twentysix 797ac6d76a Update README.md 2016-01-12 19:35:14 +01:00
Twentysix b6447e68ec Typos in trivia list 2016-01-12 15:11:25 +01:00
Twentysix 96fb81581e A new list and some small fixes to the others 2016-01-12 13:56:32 +01:00
Twentysix d86adc4509 Added !debug and 2 lists of questions 2016-01-12 12:14:00 +01:00
Twentysix 15e727ef4c Update README.md 2016-01-11 22:09:31 +01:00
Twentysix 4bce1994d0 Hotfix for trivia
In case it runs out of questions in the current list
2016-01-11 21:31:39 +01:00
Twentysix a3482f939a Trivia system and 2 lists of questions
!trivia
2016-01-11 18:59:32 +01:00
Twentysix 8cd50a1cbb Update README.md 2016-01-10 23:06:09 +01:00
Twentysix 761bd7eb2c Fixed local playlists for Linux
glob module gave different results on Linux.
Most likely fixed
2016-01-10 08:27:45 +01:00
Twentysix 2e78a3f829 Minor fixes 2016-01-10 07:43:33 +01:00
Twentysix 03332be3aa !cleanup improved, admin help added
!cleanup [name/mention] [number] - Deletes last [number] messages of
[name]
!admin help
2016-01-09 16:03:36 +01:00
Twentysix 385ee1b409 Update README.md 2016-01-09 08:15:03 +01:00
crysis909 e293d0546c New Command [!urban]
Added Urban Dictionary
2016-01-09 00:15:51 +01:00
Twentysix be4ccc4bfc Hotfix for twitch alert system
Streams were erroneously marked as inexistant in case of error. Most
likely fixed.
2016-01-08 20:54:27 +01:00
Twentysix cc8b4b0585 Merge pull request #6 from rookwood101/patch-1
Fixed typo that allowed arbitrary volumes
2016-01-08 18:40:49 +01:00
Alex Sadler e1c4edba9f Fix typo which allowed arbitrary volumes 2016-01-08 15:14:06 +00:00
Twentysix 7a82c9ec68 Twitch alert system, custom commands' list
Added !twitchalert !stoptwitchalert to add and remove online alerts
about the specified streamer in the channel
Added !customcommands for the custom commands list of the server
Added startRedLoop.bat for automatically restarting the bot in case of
crash
2016-01-08 15:56:21 +01:00
Twentysix c722c9e117 Fixed !choose
Behaved incorrectly with only two choices
2016-01-06 21:20:10 +01:00
Twentysix cd597b1665 Update README.md 2016-01-06 07:28:56 +01:00
Twentysix 47e9c657b2 Added download mode and !volume
Added download mode since streaming is buggy. This is now the default
mode and can be turned on and off with !downloadmode
Added !volume [0-1]
2016-01-05 16:52:19 +01:00
Twentysix 0ac2a02968 Update README.md 2016-01-05 01:06:54 +01:00
Twentysix 2d312292ea Added !avatar [name or mention] 2016-01-05 00:06:20 +01:00
Twentysix 9eafd44ec8 Update README.md 2016-01-04 18:36:59 +01:00
Twentysix fbea3e91dd Added local mp3/flac support 2016-01-04 18:02:45 +01:00
Twentysix a6193e1f37 Hotfix for recent discord.py change 2016-01-04 05:04:44 +01:00
Twentysix 1e8b9ab681 Fixed !reload and !getplaylist
!reload now works and !getplaylist splits the message in multiple parts
2016-01-04 04:37:04 +01:00
Twentysix cf5e07851b Name restrictions removed, settings check (...)
Name restrictions have been removed. It no longer force upon the user
the .Name() format. Settings are now checked every boot for consistency.
Slot machine now shows credits left every play
2016-01-03 15:58:43 +01:00
Twentysix bb96050eaf Update README.md 2016-01-03 09:21:40 +01:00
Twentysix a871267b11 Added startRed.bat for easier bug reports 2016-01-03 08:53:37 +01:00
Twentysix d5eb0a9db1 Fixed !youtube
!youtube wasn't working correctly with !pause, !resume and favorites
2016-01-03 08:31:09 +01:00
Twentysix 6f6963b1af Update README.md 2016-01-03 07:01:31 +01:00
Twentysix 6e3fa6b73f Properly check for permissions. Updated README 2016-01-03 04:19:26 +01:00
Twentysix 01a69d2ebc Name check at start and updated README 2016-01-02 16:44:09 +01:00
Twentysix26 71eade46f8 Fixed README.md 2016-01-02 15:36:51 +01:00
Twentysix26 cb2451c04e Fixed README.md. Again. 2016-01-02 11:12:51 +01:00
Twentysix26 179feb155f Fixed README.md 2016-01-02 11:05:00 +01:00
Twentysix 94b98c2535 Added favorites folder 2016-01-02 10:42:15 +01:00
Twentysix 18061321cb First commit 2016-01-02 10:25:47 +01:00
Twentysix 4d6930c3a7 🎊 Added .gitattributes & .gitignore files 2016-01-02 10:14:18 +01:00
650 changed files with 5276 additions and 67158 deletions
+17
View File
@@ -0,0 +1,17 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
-58
View File
@@ -1,58 +0,0 @@
# Default
* @Twentysix26
# Core
redbot/core/bank.py @palmtree5
redbot/core/checks.py @tekulvw
redbot/core/cli.py @tekulvw
redbot/core/config.py @tekulvw
redbot/core/cog_manager.py @tekulvw
redbot/core/core_commands.py @tekulvw
redbot/core/context.py @Tobotimus
redbot/core/data_manager.py @tekulvw
redbot/core/dev_commands.py @tekulvw
redbot/core/drivers/* @tekulvw
redbot/core/events.py @tekulvw
redbot/core/global_checks.py @tekulvw
redbot/core/i18n.py @tekulvw
redbot/core/json_io.py @tekulvw
redbot/core/modlog.py @palmtree5
redbot/core/rpc.py @tekulvw
redbot/core/sentry_setup.py @Kowlin @tekulvw
redbot/core/utils/chat_formatting.py @tekulvw
redbot/core/utils/mod.py @palmtree5
redbot/core/utils/data_converter.py @mikeshardmind
redbot/core/utils/antispam.py @mikeshardmind
redbot/core/utils/tunnel.py @mikeshardmind
# Cogs
redbot/cogs/admin/* @tekulvw
redbot/cogs/alias/* @tekulvw
redbot/cogs/audio/* @aikaterna @atiwiex
redbot/cogs/bank/* @tekulvw
redbot/cogs/cleanup/* @palmtree5
redbot/cogs/customcom/* @palmtree5
redbot/cogs/downloader/* @tekulvw
redbot/cogs/economy/* @palmtree5
redbot/cogs/filter/* @palmtree5
redbot/cogs/general/* @palmtree5
redbot/cogs/image/* @palmtree5
redbot/cogs/mod/* @palmtree5
redbot/cogs/modlog/* @palmtree5
redbot/cogs/streams/* @Twentysix26 @palmtree5
redbot/cogs/trivia/* @Tobotimus
redbot/cogs/dataconverter/* @mikeshardmind
redbot/cogs/reports/* @mikeshardmind
# Docs
docs/* @tekulvw @palmtree5
# Setup, instance setup, and running the bot
setup.py @tekulvw
redbot/__init__.py @tekulvw
redbot/__main__.py @tekulvw
redbot/setup.py @tekulvw
# Others
.travis.yml @Kowlin
crowdin.yml @Kowlin
-75
View File
@@ -1,75 +0,0 @@
# Introduction
### Welcome!
First off, thank you for contributing to the further development of Red. We're always looking for new ways to improve our project and we appreciate any help you can give us.
### Why do these guidelines exist?
Red is an open source project. This means that each and every one of the developers and contributors who have helped make Red what it is today have done so by volunteering their time and effort. It takes a lot of time to coordinate and organize issues and new features and to review and test pull requests. By following these guidelines you will help the developers streamline the contribution process and save them time. In doing so we hope to get back to each and every issue and pull request in a timely manner.
### What kinds of contributions are we looking for?
We love receiving contributions from our community. Any assistance you can provide with regards to bug fixes, feature enhancements, and documentation is more than welcome.
# Ground Rules
We've made a point to use [ZenHub](https://www.zenhub.com/) (a plugin for GitHub) as our main source of collaboration and coordination. Your experience contributing to Red will be greatly improved if you go get that plugin.
1. Ensure cross compatibility for Windows, Mac OS and Linux.
2. Ensure all Python features used in contributions exist and work in Python 3.5 and above.
3. Create new tests for code you add or bugs you fix. It helps us help you by making sure we don't accidentally break anything :grinning:
4. Create any issues for new features you'd like to implement and explain why this feature is useful to everyone and not just you personally.
5. Don't add new cogs unless specifically given approval in an issue discussing said cog idea.
6. Be welcoming to newcomers and encourage diverse new contributors from all backgrounds. See [Python Community Code of Conduct](https://www.python.org/psf/codeofconduct/).
# Your First Contribution
Unsure of how to get started contributing to Red? Please take a look at the Issues section of this repo and sort by the following labels:
* beginner - issues that can normally be fixed in just a few lines of code and maybe a test or two.
* help-wanted - issues that are currently unassigned to anyone and may be a bit more involved/complex than issues tagged with beginner.
**Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)
At this point you're ready to start making changes. Feel free to ask for help; everyone was a beginner at some point!
# Getting Started
### Testing
We've recently started adding unit-testing into Red. All current tests can be found in the `tests/` directory at the root level of the repository. You will need `py.test` installed in order to run them (which is already in `requirement.txt`). Tests can be run by simply calling `pytest` once you've `cd`'d into the Red repository folder.
### To contribute changes
1. Create your own fork of the Red repository.
2. Make the changes in your own fork.
3. If you like the changes and think the main Red project could use it:
* Ensure your code follows (generally) the PEP8 Python style guide
* Create a Pull Request on GitHub with your changes
### How To Report A Bug
Please see our **ISSUES.MD** for more information.
### How To Suggest A Feature Or Enhancement
The goal of Red is to be as useful to as many people as possible, this means that all features must be useful to anyone and any server that uses Red.
If you find yourself wanting a feature that Red does not already have, you're probably not alone. There's bound to be a great number of users out there needing the same thing and a lot of the features that Red has today have been added because of the needs of our users. Open an issue on our issues list and describe the feature you would like to see, how you would use it, how it should work, and why it would be useful to the Red community as a whole.
# Code Review Process
We have a core team working tirelessly to implement new features and fix bugs for the Red community. This core team looks at and evaluates new issues and PRs on a daily basis.
The decisions we make are based on a simple majority of that team or by decree of the project owner.
### Issues
Any new issues will be looked at and evaluated for validity of a bug or for the usefulness of a suggested feature. If we have questions about your issue we will get back as soon as we can (usually in a day or two) and will try to make a decision within a week.
### Pull Requests
Pull requests are evaluated by their quality and how effectively they solve their corresponding issue. The process for reviewing pull requests is as follows:
1. A pull request is submitted
2. Core team members will review and test the pull request (usually within a week)
3. After a majority of the core team approves your pull request:
* If your pull request is considered an improvement or enhancement the project owner will have 1 day to veto or approve your pull request.
* If your pull request is considered a new feature the project owner will have 1 week to veto or approve your pull request.
4. If any feedback is given we expect a response within 1 week or we may decide to close the PR.
5. If your pull request is not vetoed and no core member requests changes then it will be approved and merged into the project.
### Differences between "new features" and "improvements"
The difference between a new feature and improvement can be quite fuzzy and the project owner reserves all rights to decide under which category your PR falls.
At a very basic level a PR is a new feature if it changes the intended way any part of the Red project currently works or if it modifies the user experience (UX) in any significant way. Otherwise, it is likely to be considered an improvement.
# Community
You can chat with the core team and other community members about issues or pull requests in the #coding channel of the Red support server located [here](https://discord.gg/red).
-20
View File
@@ -1,20 +0,0 @@
Please be sure to read through other issues as well to make sure what you are suggesting/reporting has not already
been suggested/reported
### Type:
- [ ] Suggestion
- [ ] Bug
### Brief description of the problem
### Expected behavior
### Actual behavior
### Steps to reproduce
1.
2.
3.
4.
-25
View File
@@ -1,25 +0,0 @@
# Command bugs
<!--
Did you find a bug with a command? Fill out the following:
-->
#### Command name
<!-- Replace this line with the name of the command -->
#### What cog is this command from?
<!-- Replace this line with the name of the cog -->
#### What were you expecting to happen?
<!-- Replace this line with a description of what you were expecting to happen -->
#### What actually happened?
<!-- Replace this line with a description of what actually happened. Include any error messages -->
#### How can we reproduce this issue?
<!-- Replace with numbered steps to reproduce the issue -->
-35
View File
@@ -1,35 +0,0 @@
# Feature request
<!-- This template is for feature requests. Please fill out the following: -->
#### Select the type of feature you are requesting:
<!-- To check a box, replace the space between the [] with a x -->
- [ ] Cog
- [ ] Command
- [ ] API functionality
#### Describe your requested feature
<!--
Feel free to describe in as much detail as you wish.
If you are requesting a cog to be included in core:
- Describe the functionality in as much detail as possible
- Include the command structure, if possible
- Please note that unless it's something that should be core functionality,
we reserve the right to reject your suggestion and point you to our cog
board to request it for a third-party cog
If you are requesting a command:
- Include what cog it should be in and a name for the command
- Describe the intended functionality for the command
- Note any restrictions on who can use the command or where it can be used
If you are requesting API functionality:
- Describe what it should do
- Note whether it is to extend existing functionality or introduce new functionality
-->
-21
View File
@@ -1,21 +0,0 @@
# Other bugs
<!--
Did you find a bug with something other than a command? Fill out the following:
-->
#### What were you trying to do?
<!-- Replace this line with a description of what you were trying to do -->
#### What were you expecting to happen?
<!-- Replace this line with a description of what you were expecting to happen -->
#### What actually happened?
<!-- Replace this line with a description of what actually happened. Include any error messages -->
#### How can we reproduce this issue?
<!-- Replace with numbered steps to reproduce the issue -->
@@ -1,7 +0,0 @@
### Type
- [ ] Bugfix
- [ ] Enhancement
- [ ] New feature
### Description of the changes
-14
View File
@@ -1,14 +0,0 @@
# Bugfix request
<!--
To be used for pull requests that fix a bug
-->
#### Describe the bug being fixed
<!--
If an issue exists for the bug, mention
that this PR fixes that issue
-->
#### Anything we need to know about this fix?
@@ -1,20 +0,0 @@
# Enhancement request
<!--
To be used for PRs which enhance existing features
-->
#### Describe the enhancement
<!--
Describe what your changes do.
If adding commands, describe any restrictions on their usage.
- For example, who can use the command? Where can it be used?
-->
#### Does this enhancement break existing functionality?
<!-- To check a box, replace the space between the [] with a x -->
- [ ] Yes
- [ ] No
@@ -1,21 +0,0 @@
# New feature addition
<!--
To be used for PRs which add a new feature
Examples of this include new APIs, new core cogs, etc.
-->
#### What type of feature is this?
<!-- To check a box, replace the space between the [] with a x -->
- [ ] New core cog
- [ ] New API
- [ ] Other
#### Describe the feature
<!--
If you are adding a cog, describe its commands in detail (functionality, usage restrictions, etc).
If the new feature introduces new requirements, please try to explain why they are necessary.
-->
-16
View File
@@ -1,16 +0,0 @@
# New release
<!--
To be used by collaborators for doing releases.
Most contributors will not need to use this.
-->
#### Version
#### Has a draft release been created for this?
- [ ] Yes
- [ ] No
@@ -1,5 +0,0 @@
# Translations update
<!--
Used for PRs updating translations from Crowdin
-->
+40 -150
View File
@@ -1,160 +1,50 @@
# Trivia list repo injection
redbot/trivia/
# Windows image file caches
Thumbs.db
ehthumbs.db
*.json
*.exe
*.dll
.data
# Folder config file
Desktop.ini
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# Recycle Bin used on file shares
$RECYCLE.BIN/
# User-specific stuff:
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
# Windows shortcuts
*.lnk
# Gradle:
.idea/**/gradle.xml
.idea/**/libraries
# =========================
# Operating System Files
# =========================
# CMake
cmake-build-debug/
# OSX
# =========================
# Mongo Explorer plugin:
.idea/**/mongoSettings.xml
.DS_Store
.AppleDouble
.LSOverride
## File-based project format:
*.iws
# Thumbnails
._*
## Plugin-specific files:
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# pytest
.pytest_cache/
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
__pycache__
json
cache
-14
View File
@@ -1,14 +0,0 @@
formats:
- pdf
build:
image: latest
requirements_file: docs/requirements.txt
python:
version: 3.6
pip_install: true
extra_requirements:
- docs
- mongo
-54
View File
@@ -1,54 +0,0 @@
dist: trusty
language: python
cache: pip
notifications:
email: false
python:
- 3.5.3
- 3.6.1
install:
- echo "git+https://github.com/Rapptz/discord.py.git@rewrite#egg=discord.py[voice]" >> requirements.txt
- pip install -r requirements.txt
- pip install .[test]
script:
- python -m compileall ./redbot/cogs
- python -m pytest
jobs:
include:
- stage: PyPi Deployment
if: tag IS present
python: 3.5.3
env:
- DEPLOYING=true
deploy:
- provider: pypi
user: Red-DiscordBot
password:
secure: Ty9vYnd/wCuQkVC/OsS4E2jT9LVDVfzsFrQc4U2hMYcTJnYbl/3omyObdCWCOBC40vUDkVHAQU8ULHzoCA+2KX9Ds/7/P5zCumAA0uJRR9Smw7OlRzSMxJI+/lGq4CwXKzxDZKuo5rsxXEbW5qmYjtO8Mk6KuLkvieb1vyr2DcqWEFzg/7TZNDfD1oP8et8ITQ26lLP1dtQx/jlAiIBzgK9wziuwj1Divb9A///VsGz43N8maZ+jfsDjYqrfUVWTy3ar7JPUplletenYCR1PmQ5C46XfV0kitKd1aITJ48YPAKyYgKy8AIT+Uz1JArTnqdzLSFRNELS57qS00lzgllbteCyWQ8Uzy0Zpxb/5DDH8/mL1n0MyJrF8qjZd2hLNAXg3z/k9bGXeiMLGwoxRlGXkL2XpiVgI93UKKyVyooGNMgPTc/QdSc7krjAWcOtX/HgLR34jxeLPFEdzJNAFIimfDD8N+XTFcNBw6EvOYm/n5MXkckNoX/G+ThNobHZ7VKSASltZ9zBRAJ2dDh35G3CYmVEk33U77RKbL9le/Za9QVBcAO8i6rqVGYkdO7thHHKHc/1CB1jNnjsFSDt0bURtNfAqfwKCurQC8487zbEzT+2fog3Wygv7g3cklaRg4guY8UjZuFWStYGqbroTsOCd9ATNqeO5B13pNhllSzU=
skip_cleanup: true
on:
repo: Cog-Creators/Red-DiscordBot
branch: V3/develop
python: 3.5.3
tags: true
- stage: Crowdin Deployment
if: tag IS present
python: 3.5.3
env:
- DEPLOYING=true
before_deployment:
- curl https://artifacts.crowdin.com/repo/GPG-KEY-crowdin | sudo apt-key add -
- echo "deb https://artifacts.crowdin.com/repo/deb/ /" | sudo tee -a /etc/apt/sources.list
- sudo apt-get update -qq
- sudo apt-get install -y crowdin
deploy:
- provider: script
script: python3 ./generate_strings.py
skip_cleanup: true
on:
repo: Cog-Creators/Red-DiscordBot
branch: V3/develop
python: 3.5.3
tags: true
+4 -4
View File
@@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Red - A fully customizable Discord bot
Copyright (C) 2015-2018 Twentysix
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Red-DiscordBot Copyright (C) 2015-2018 Twentysix
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-5
View File
@@ -1,5 +0,0 @@
include README.rst
include LICENSE
include requirements.txt
include discord/bin/*.dll
include redbot/cogs/audio/application.yml
+144
View File
@@ -0,0 +1,144 @@
# Red - A multifunction Discord bot
#### *Fun bringer, admin helper and music bot*
[<img align="right" title="Art by Supergiant Games" src="https://www.supergiantgames.com/static/images/transistor/cartoon_red.png">](https://www.supergiantgames.com/games/transistor/)
[<img src="https://img.shields.io/badge/Support-me!-orange.svg">](https://www.patreon.com/Twentysix26) [<img src="https://img.shields.io/badge/Official-Server-green.svg">](https://discord.gg/0k4npTwMvTpv9wrh) **< Announcements & Help!**
##**[ [This version is obsolete and no longer being supported. Use the current one] ](https://github.com/Twentysix26/Red-DiscordBot/)**
### Cool title, but what does it do exactly?
A bit of everything. Seriously though:
It has the [most common features](#general-commands) of many chatbots (!flip, !8, stopwatch, etc.), **custom commands** (inspired by Twitch's [Nightbot](https://www.nightbot.tv/)), memes.
It features some games such as **Trivia**, rock paper scissors, [users can earn and play with credits](#economy-commands) in the slot machine.
[The audio part is quite fleshed out](#audio-commands). Users can **stream youtube videos**, create **playlists** that everyone will be able to play and control (previous/next song, pause/resume, shuffle...).
**MP3 and flac files can also be streamed** (see [FAQ](#faq) for details on local playlists)
**Twitch's online notifications**: Red will notify the channels you want whenever you favorite Twitch streamers are online.
As for the moderation tools, it includes a **powerful message filter with regular expression capabilities** and **mass messages cleanup**.
[I'm planning to expand all this much more](#todo-list).
See the [command list](#general-commands) for an even better idea of what this bot can do.
### I don't even know what I'm looking at. How do I install this?
Do not panic. [Enter the wiki and follow the tutorials](https://github.com/Twentysix26/Red-DiscordBot/wiki)!
If you have any issue, consult the [troubleshooting](https://github.com/Twentysix26/Red-DiscordBot/wiki/Troubleshooting) page, and if you're still stuck, [join the official server](https://discord.gg/0k4npTwMvTpv9wrh) so you can get some help.
Once you're done, take a look at the command list and have fun.
### General commands
| Command | Description |
|-----------------------------------------------|--------------------------------------------|
| !flip | Flip a coin |
| !rps [rock/paper/scissors] | Play RPS |
| !proverb | Random proverb |
| !choose [option1 or option2 or option3 (...)] | Random choice. Supports multiple words |
| !8 [question?] | Ask 8 ball a question |
| !sw | Start/stop the stopwatch |
| !trivia | Trivia help and lists |
| !trivia [list] | Start a trivia session |
| !trivia stop | Stop a trivia session |
| !twitch [stream] | Check if stream is online |
| !twitchalert [stream] | Red sends an alert in the channel when the stream is online (admin only)|
| !stoptwitchalert [stream] | Stop stream alerts (admin only) |
| !roll [number] | Random number between 0 and chosen number. |
| !gif [text] | GIF search |
| !imdb [movie/etc] | Retrieve information from IMDB |
| !meme [id;text1;text2] | Create a meme |
| !poll [question;answer1;answer2 (...)] | Start poll in the current channel |
| !endpoll | Stop poll |
| !addcom [command] [text] | Add a custom command |
| !editcom [command] [text] | Edit a custom command |
| !delcom [command] | Delete a custom command |
| !customcommands | Custom commands' list |
| !help | Command list |
| !audio help | Audio command list and playlist explanation.|
| !economy | Explanation of the economy module |
| !admin help | Admin commands list |
| !meme help | Explanation of !meme |
### Audio commands
| Command | Description |
|----------------------------|---------------------------------------------------------------------|
| !youtube [link] | Play a youtube video in a voice channel |
| !sing | Make Red sing |
| !stop | Stop any voice channel activity |
| !play [playlist_name] | Play chosen playlist |
| !playlists | Playlist's list |
| !next or !skip | Next song |
| !prev | Previous song |
| !pause | Pause song |
| !resume | Resume song |
| !replay or !repeat | Replay current song |
| !title or !song | Current song's title + link |
| !shuffle | Mix current playlist |
| !volume [0-1] | Sets Red's output volume |
| !addplaylist [name] [link] | Add a youtube playlist |
| !delplaylist [name] | Delete a youtube playlist. Limited to author and admins |
| !getplaylist | Get the current playlist through DM. This also works with favorites |
| !addfavorite | Add song to your favorites |
| !delfavorite | Remove song from your favorites |
| !playfavorites | Play your favorites |
| !local [playlist_name] | Play chosen local playlist |
| !local or !locallist | Local playlists' list |
| !downloadmode | Enables or disables download mode. (admin only) |
### Admin commands
| Command | Description |
|-----------------------------------------------------------|---------------------------------------------------|
| !addwords [word1 word2 (...)] [phrase/with/many/words] | Add words to message filter |
| !removewords [word1 word2 (...)] [phrase/with/many/words] | Remove words from message filter |
| !addregex [regex] | Add regular expression to message filter |
| !removeregex [regex] | Remove regular expression from message filter |
| !shutdown | Close the bot |
| !join [invite] | Join another server |
| !leaveserver | Leave server |
| !shush | Ignore the current channel |
| !talk | Stop ignoring the current channel |
| !reload | Reload most files. Useful in case of manual edits |
| !name [name] | Change the bot's name |
| !cleanup [number] | Delete the last [number] messages |
| !cleanup [name/mention] [number] | Delete the last [number] of messages by [name] |
| !blacklist [name/mention] | Add user to blacklist. Red will ignore that user |
| !forgive [name/mention] | Remove user from blacklist |
| !setting [setting] [value] | Modify setting |
### Economy commands
| Command | Description |
|-------------|--------------------------------------|
| !register | Register a new account |
| !balance | Check your balance |
| !slot [bid] | Play the slot machine |
| !slot help | Slot machine explanation and payouts |
| !payday | Receive credits |
### FAQ
>I've done everything the README asked me to and it still doesn't work! Were you drunk when you coded this?
You're probably missing something.
Feel free to join [my server](https://discord.gg/0k4npTwMvTpv9wrh) and head to #support to get some help! Oh, and my drinking habits are none of your business.
>Does this bot work on multiple servers?
Sure it does. Should you do it? Maybe. The permissions system is not that great at the moment but if you trust the people running the server it's ok. It's not advisable to send the bot in random servers at the moment.
Custom commands only work in the server they were created in. Same for the message filter. This is by design. Also, remember that the bot can only be in one voice channel at once.
>Will you implement [feature]?
Suggestions are always very welcome.
>How do local playlists work?
Make as many folders as you want inside the localtracks folder. Names must be without spaces. Every folder counts as a different playlist. Every playlist can contain mp3 and flac files. Users can stream them by doing !local [playlist_name] and see the full list
with !local or !locallist. They can also add tracks to their favorites.
>What's download mode?
Everytime you play the audio of a youtube video with download mode on the audio will be first downloaded and stored into the "cache" folder. It is recommended that you use this mode to avoid streaming problems. This is the default mode, you can switch between modes with !downloadmode.
>Why is this bot called Red and the admin role "Transistor"? What's the meaning of !sing?
They're all references to [Transistor](https://www.supergiantgames.com/games/transistor/), a videogame by Supergiant Games.
### TODO List
- [x] [Start rewriting Red](https://github.com/Twentysix26/Red-DiscordBot/tree/develop)
- [ ] ~~Bundle some malware and slowly build up a botnet for world domination~~
-42
View File
@@ -1,42 +0,0 @@
.. image:: https://readthedocs.org/projects/red-discordbot/badge/?version=v3-develop
:target: http://red-discordbot.readthedocs.io/en/v3-develop/?badge=v3-develop
:alt: Documentation Status
.. image:: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
:target: http://makeapullrequest.com
:alt: PRs Welcome
.. image:: https://d322cqt584bo4o.cloudfront.net/red-discordbot/localized.svg
:target: https://crowdin.com/project/red-discordbot
:alt: Crowdin
.. image:: https://img.shields.io/badge/Support-Red!-orange.svg
:target: https://www.patreon.com/Red_Devs
:alt: Patreon
********************
Red - Discord Bot v3
********************
**This is in beta and very much a work in progress. Regular use is not recommended.
There will not be any effort made to prevent the breaking of current installations.**
How to install
^^^^^^^^^^^^^^
Using python3 pip::
pip install --process-dependency-links -U Red-DiscordBot
redbot-setup
redbot <name>
To install requirements for voice::
pip install --process-dependency-links -U Red-DiscordBot[voice]
To install all requirements for docs and tests::
pip install --process-dependency-links -U Red-DiscordBot[test,docs]
For the latest git build, replace ``Red-DiscordBot`` in the above commands with
``git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop``.
-5
View File
@@ -1,5 +0,0 @@
api_key_env: CROWDIN_API_KEY
project_identifier_env: CROWDIN_PROJECT_ID
files:
- source: /**/*.pot
translation: /%original_path%/%locale%.po
+132
View File
@@ -0,0 +1,132 @@
import json
import logging
import os
import glob
default_settings = ('{"TRIVIA_ADMIN_ONLY": false, "EDIT_CC_ADMIN_ONLY": false, "PASSWORD": "PASSWORDHERE", "FILTER": true, "CUSTOMCOMMANDS": true, ' +
'"TRIVIA_MAX_SCORE": 10, "TRIVIA_DELAY": 15, "LOGGING": true, "EMAIL": "EMAILHERE", "ADMINROLE": "Transistor", "DOWNLOADMODE" : true, ' +
'"VOLUME": 0.20, "TRIVIA_BOT_PLAYS" : false, "TRIVIA_TIMEOUT" : 120, "DEBUG_ID" : "IgnoreThis", "POLL_DURATION" : 60, "PREFIX" : "!"}')
default_apis = ('{"IMGFLIP_USERNAME": "USERNAMEHERE", "IMGFLIP_PASSWORD": "PASSWORDHERE", "MYAPIFILMS_TOKEN" : "TOKENHERE"}')
logger = logging.getLogger("__main__")
def fileIO(filename, IO, data=None):
if IO == "save" and data != None:
with open(filename, encoding='utf-8', mode="w") as f:
f.write(json.dumps(data))
elif IO == "load" and data == None:
with open(filename, encoding='utf-8', mode="r") as f:
return json.loads(f.read())
elif IO == "check" and data == None:
try:
with open(filename, encoding='utf-8', mode="r") as f:
return True
except:
return False
else:
logger.info("Invalid fileIO call")
def loadProverbs():
with open("proverbs.txt", encoding='utf-8', mode="r") as f:
data = f.readlines()
return data
def loadAndCheckSettings():
to_delete = []
try:
current_settings = fileIO("json/settings.json", "load")
default = json.loads(default_settings)
if current_settings.keys() != default.keys():
logger.warning("Something wrong detected with settings.json. Starting check...")
for field in default:
if field not in current_settings:
logger.info("Adding " + field + " field.")
current_settings[field] = default[field]
for field in current_settings:
if field not in default:
logger.info("Removing " + field + " field.")
to_delete.append(field)
for field in to_delete:
del current_settings[field]
logger.warning("Your settings.json was deprecated (missing or useless fields detected). I fixed it. " +
"If the file was missing any field I've added it and put default values. You might want to check it.")
fileIO("json/settings.json", "save", current_settings)
return current_settings
except IOError:
fileIO("json/settings.json", "save", json.loads(default_settings))
logger.error("Your settings.json is missing. I've created a new one. Edit it with your settings and restart me.")
exit(1)
except:
logger.error("Your settings.json seems to be invalid. Check it. If you're unable to fix it delete it and I'll create a new one the next start.")
exit(1)
def migration():
if not os.path.exists("json/"):
os.makedirs("json")
logger.info("Creating json folder...")
if not os.path.exists("cache/"): #Stores youtube audio for DOWNLOADMODE
os.makedirs("cache")
if not os.path.exists("trivia/"):
os.makedirs("trivia")
files = glob.glob("*.json")
if files != []:
logger.info("Moving your json files into the json folder...")
for f in files:
logger.info("Moving {}...".format(f))
os.rename(f, "json/" + f)
def createEmptyFiles():
files = {"twitch.json": [], "commands.json": {}, "economy.json" : {}, "filter.json" : {}, "regex_filter.json" : {}, "shushlist.json" : [], "blacklist.json" : []}
games = ["Multi Theft Auto", "her Turn()", "Tomb Raider II", "some music.", "NEO Scavenger", "Python", "World Domination", "with your heart."]
files["games.json"] = games
for f, data in files.items() :
if not os.path.isfile("json/" + f):
logger.info("Missing {}. Creating it...".format(f))
fileIO("json/" + f, "save", data)
if not os.path.isfile("json/settings.json"):
logger.info("Missing settings.json. Creating it...\n")
fileIO("json/settings.json", "save", json.loads(default_settings))
print("You have to configure your settings. If you'd like to do it manually, close this window.\nOtherwise type your bot's account email. DO NOT use your own account for the bot, make a new one.\n\nEmail:")
email = input(">")
print("Now enter the password.")
password = input(">")
print("Admin role? Leave empty for default (Transistor)")
admin_role = input(">")
if admin_role == "":
admin_role = "Transistor"
print("Command prefix? Leave empty for default, '!'. Maximum 1 character.")
prefix = input(">")
if len(prefix) != 1 or prefix == " ":
print("Invalid prefix. Setting prefix as '!'...")
prefix = "!"
new_settings = json.loads(default_settings)
new_settings["EMAIL"] = email
new_settings["PASSWORD"] = password
new_settings["ADMINROLE"] = admin_role
new_settings["PREFIX"] = prefix
fileIO("json/settings.json", "save", new_settings )
logger.info("Settings have been saved.")
if not os.path.isfile("json/apis.json"):
logger.info("Missing apis.json. Creating it...\n")
fileIO("json/apis.json", "save", json.loads(default_apis))
print("\nIt's now time to configure optional services\nIf you're not interested, leave empty and keep pressing enter.\nMemes feature: create an account on https://imgflip.com/.\nimgflip username:")
imgflip_username = input(">")
print("Now enter the imgflip password.")
imgflip_password = input(">")
if imgflip_username == "": imgflip_username = "USERNAMEHERE"
if imgflip_password == "": imgflip_password = "PASSWORDHERE"
print("\n!imdb configuration. Get your token here http://www.myapifilms.com/token.do\nOr just press enter if you're not interested.")
imdb_token = input(">")
if imdb_token == "": imdb_token = "TOKENHERE"
new_settings = json.loads(default_apis)
new_settings["IMGFLIP_USERNAME"] = imgflip_username
new_settings["IMGFLIP_PASSWORD"] = imgflip_password
new_settings["MYAPIFILMS_TOKEN"] = imdb_token
fileIO("json/apis.json", "save", new_settings )
logger.info("API Settings have been saved.\n")
-20
View File
@@ -1,20 +0,0 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = python -msphinx
SPHINXPROJ = Red-DiscordBot
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-48
View File
@@ -1,48 +0,0 @@
.. systemd service guide
==========================
Setting up auto-restart using systemd on Linux
==========================
---------------------------
Creating the service file
---------------------------
Create the new service file:
:code:`sudo nano /etc/systemd/system/red@.service`
Paste the following and replace all instances of :code:`username` with the username your bot is running under (hopefully not root):
.. code-block:: none
[Unit]
Description=%I redbot
After=multi-user.target
[Service]
ExecStart=/home/username/.local/bin/redbot %I --no-prompt
User=username
Group=username
Type=idle
Restart=always
RestartSec=15
[Install]
WantedBy=multi-user.target
Save and exit :code:`ctrl + O; enter; ctrl + x`
---------------------------
Starting and enabling the service
---------------------------
To start the bot, run the service and add the instance name after the **@**:
:code:`sudo systemctl start red@instancename`
To set the bot to start on boot, you must enable the service, again adding the instance name after the **@**:
:code:`sudo systemctl enable red@instancename`
.. note:: This same file can be used to start as many instances of the bot as you wish, without creating more service files, just start and enable more services and add any bot instance name after the **@**
-62
View File
@@ -1,62 +0,0 @@
.. Importing data from a V2 install
================================
Importing data from a V2 install
================================
----------------
What you'll need
----------------
1. A Running V3 bot
2. The path where your V2 bot is installed
--------------
Importing data
--------------
.. important::
Unless otherwise specified, the V2 data will take priority over V3 data for the same entires
.. important::
For the purposes of this guide, your prefix will be denoted as
[p]
You should swap whatever you made your prefix in for this.
All of the below are commands to be entered in discord where the bot can
see them.
The dataconverter cog is not loaded by default. To start, load it with
.. code-block:: none
[p]load dataconverter
Next, you'll need to give it the path where your V2 install is.
On linux and OSX, it may look something like:
.. code-block:: none
/home/username/Red-DiscordBot/
On Windows it will look something like:
.. code-block:: none
C:\Users\yourusername\Red-DiscordBot
Once you have that path, give it to the bot with the following command
(make sure to swap your own path in)
.. code-block:: none
[p]convertdata /home/username/Red-DiscordBot/
From here, if the path is correct, you will be prompted with an interactive menu asking you
what data you would like to import
You can select an entry by number, or quit with any of 'quit', 'exit', 'q', '-1', or 'cancel'
-9
View File
@@ -1,9 +0,0 @@
.. Downloader Cog Reference
Downloader Cog Reference
========================
.. automodule:: redbot.cogs.downloader
.. autoclass:: redbot.cogs.downloader.downloader.Downloader
:members:
-197
View File
@@ -1,197 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Red - Discord Bot documentation build configuration file, created by
# sphinx-quickstart on Thu Aug 10 23:18:25 2017.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
os.environ['BUILDING_DOCS'] = "1"
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
'sphinxcontrib.asyncio'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'Red - Discord Bot'
copyright = '2018, Cog Creators'
author = 'Cog Creators'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
from redbot.core import __version__
# The short X.Y version.
version = __version__
# The full version, including alpha/beta/rc tags.
release = __version__
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# Role which is assigned when you make a simple reference within backticks
default_role = "any"
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
html_context = {
# Enable the "Edit in GitHub link within the header of each page.
'display_github': True,
'github_user': 'Cog-Creators',
'github_repo': 'Red-DiscordBot',
'github_version': 'V3/develop/docs/'
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# This is required for the alabaster theme
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
html_sidebars = {
'**': [
'about.html',
'navigation.html',
'relations.html', # needs 'show_related': True theme option to display
'searchbox.html',
'donate.html',
]
}
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'Red-DiscordBotdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'Red-DiscordBot.tex', 'Red - Discord Bot Documentation',
'Cog Creators', 'manual'),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'red-discordbot', 'Red - Discord Bot Documentation',
[author], 1)
]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'Red-DiscordBot', 'Red - Discord Bot Documentation',
author, 'Red-DiscordBot', 'One line description of project.',
'Miscellaneous'),
]
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'python': ('https://docs.python.org/3.5', None),
'dpy': ('https://discordpy.readthedocs.io/en/rewrite/', None),
'motor': ('https://motor.readthedocs.io/en/stable/', None)}
-42
View File
@@ -1,42 +0,0 @@
.. V3 Bank
.. role:: python(code)
:language: python
====
Bank
====
Bank has now been separated from Economy for V3. New to bank is support for
having a global bank.
***********
Basic Usage
***********
.. code-block:: python
from redbot.core import bank
class MyCog:
@commands.command()
async def balance(self, ctx, user: discord.Member=None):
if user is None:
user = ctx.author
bal = bank.get_balance(user)
currency = bank.get_currency_name(ctx.guild)
await ctx.send(
"{}'s balance is {} {}".format(
user.display_name, bal, currency
)
)
*************
API Reference
*************
Bank
======
.. automodule:: redbot.core.bank
:members:
-19
View File
@@ -1,19 +0,0 @@
.. bot module docs
===
Bot
===
.. automodule:: redbot.core.bot
RedBase
^^^^^^^
.. autoclass:: RedBase
:members:
Red
^^^
.. autoclass:: Red
:members:
-8
View File
@@ -1,8 +0,0 @@
.. cog manager docs
===========
Cog Manager
===========
.. automodule:: redbot.core.cog_manager
:members:
-388
View File
@@ -1,388 +0,0 @@
.. config shite
.. role:: python(code)
:language: python
======
Config
======
Config was introduced in V3 as a way to make data storage easier and safer for all developers regardless of skill level.
It will take some getting used to as the syntax is entirely different from what Red has used before, but we believe
Config will be extremely beneficial to both cog developers and end users in the long run.
***********
Basic Usage
***********
.. code-block:: python
from redbot.core import Config
class MyCog:
def __init__(self):
self.config = Config.get_conf(self, identifier=1234567890)
self.config.register_global(
foo=True
)
@commands.command()
async def return_some_data(self, ctx):
await ctx.send(await config.foo())
********
Tutorial
********
.. py:currentmodule:: redbot.core.config
This tutorial will walk you through how to use Config.
First, you need to import Config:
.. code-block:: python
from redbot.core import Config
Then, in the class's :code:`__init__` function, you need to get a config instance:
.. code-block:: python
class MyCog:
def __init__(self):
self.config = Config.get_conf(self, identifier=1234567890)
The ``identifier`` in :py:meth:`Config.get_conf` is used to keep your cog's data separate
from that of another cog, and thus should be unique to your cog. For example: if we
have two cogs named :code:`MyCog` and their identifier is different, each will have
its own data without overwriting the other's data. Note that it is also possible
to force registration of a data key before allowing you to get and set data for
that key by adding :code:`force_registration=True` after identifier (that defaults
to :code:`False` though)
After we've gotten that, we need to register default values:
.. code-block:: python
class MyCog:
def __init__(self):
self.config = Config.get_conf(self, identifier=1234567890)
default_global = {
"foobar": True,
"foo": {
"bar": True,
"baz": False
}
}
default_guild = {
"blah": [],
"baz": 1234567890
}
self.config.register_global(**default_global)
self.config.register_guild(**default_guild)
As seen in the example above, we can set up our defaults in dicts and then use those in
the appropriate :code:`register` function. As seen above, there's :py:meth:`Config.register_global`
and :py:meth:`Config.register_guild`, but there's also :py:meth:`Config.register_member`,
:py:meth:`Config.register_role`, :py:meth:`Config.register_user`, and :py:meth:`Config.register_channel`.
Note that :code:`member` stores based on guild id AND the user's id.
Once we have our defaults registered and we have the object, we can now use those values
in various ways:
.. code-block:: python
@commands.command()
@checks.admin_or_permissions(manage_guild=True)
async def setbaz(self, ctx, new_value):
await self.config.guild(ctx.guild).baz.set(new_value)
await ctx.send("Value of baz has been changed!")
@commands.command()
@checks.is_owner()
async def setfoobar(self, ctx, new_value):
await self.config.foobar.set(new_value)
@commands.command()
async def checkbaz(self, ctx):
baz_val = await self.config.guild(ctx.guild).baz()
await ctx.send("The value of baz is {}".format("True" if baz_val else "False"))
Notice a few things in the above examples:
1. Global doesn't have anything in between :code:`self.config` and the variable.
2. Both the getters and setters need to be awaited because they're coroutines.
3. If you're getting the value, the syntax is::
self.config.<insert scope here, or nothing if global>.variable_name()
4. If setting, it's::
self.config.<insert scope here, or nothing if global>.variable_name.set(new_value)
It is also possible to use :code:`async with` syntax to get and set config
values. When entering the statement, the config value is retreived, and on exit,
it is saved. This puts a safeguard on any code within the :code:`async with`
block such that if it breaks from the block in any way (whether it be from
:code:`return`, :code:`break`, :code:`continue` or an exception), the value will
still be saved.
.. important::
Only mutable config values can be used in the :code:`async with` statement
(namely lists or dicts), and they must be modified *in place* for their
changes to be saved.
Here is an example of the :code:`async with` syntax:
.. code-block:: python
@commands.command()
async def addblah(self, ctx, new_blah):
guild_group = self.config.guild(ctx.guild)
async with guild_group.blah() as blah:
blah.append(new_blah)
await ctx.send("The new blah value has been added!")
.. important::
Please note that while you have nothing between ``config`` and the variable name for global
data, you also have the following commands to get data specific to each category.
* :py:meth:`Config.guild` for guild data which takes an object of type :py:class:`discord.Guild`.
* :py:meth:`Config.member` which takes :py:class:`discord.Member`.
* :py:meth:`Config.user` which takes :py:class:`discord.User`.
* :py:meth:`Config.role` which takes :py:class:`discord.Role`.
* :py:meth:`Config.channel` which takes :py:class:`discord.TextChannel`.
If you need to wipe data from the config, you want to look at :py:meth:`Group.clear`, or :py:meth:`Config.clear_all`
and similar methods, such as :py:meth:`Config.clear_all_guilds`.
Which one you should use depends on what you want to do.
If you're looking to clear data for a single guild/member/channel/role/user,
you want to use :py:meth:`Group.clear` as that will clear the data only for the
specified thing.
If using :py:meth:`Config.clear_all`, it will reset all data everywhere.
There are other methods provided to reset data from a particular scope. For
example, :py:meth:`Config.clear_all_guilds` resets all guild data. For member
data, you can clear on both a per-guild and guild-independent basis, see
:py:meth:`Config.clear_all_members` for more info.
**************
Advanced Usage
**************
Config makes it extremely easy to organize data that can easily fit into one of the standard categories (global,
guild, user etc.) but there may come a time when your data does not work with the existing categories. There are now
features within Config to enable developers to work with data how they wish.
This usage guide will cover the following features:
- :py:meth:`Group.get_raw`
- :py:meth:`Group.set_raw`
For this example let's suppose that we're creating a cog that allows users to buy and own multiple pets using
the built-in Economy credits::
from redbot.core import bank
from redbot.core import Config
from discord.ext import commands
class Pets:
def __init__(self):
self.conf = Config.get_conf(self, 1234567890)
# Here we'll assign some default costs for the pets
self.conf.register_global(
dog=100,
cat=100,
bird=50
)
self.conf.register_user(
pets={}
)
And now that the cog is set up we'll need to create some commands that allow users to purchase these pets::
# continued
@commands.command()
async def get_pet(self, ctx, pet_type: str, pet_name: str):
"""
Purchase a pet.
Pet type must be one of: dog, cat, bird
"""
# Now we need to determine what the cost of the pet is and
# if the user has enough credits to purchase it.
# We will need to use "get_raw"
try:
cost = await self.conf.get_raw(pet_type)
except KeyError:
# KeyError is thrown whenever the data you try to access does not
# exist in the registered defaults or in the saved data.
await ctx.send("Bad pet type, try again.")
return
After we've determined the cost of the pet we need to check if the user has enough credits and then we'll need to
assign a new pet to the user. This is very easily done using the V3 bank API and :py:meth:`Group.set_raw`::
# continued
if await bank.can_spend(ctx.author, cost):
await self.conf.user(ctx.author).pets.set_raw(
pet_name, value={'cost': cost, 'hunger': 0}
)
# this is equivalent to doing the following
pets = await self.conf.user(ctx.author).pets()
pets[pet_name] = {'cost': cost, 'hunger': 0}
await self.conf.user(ctx.author).pets.set(pets)
Since the pets can get hungry we're gonna need a command that let's pet owners check how hungry their pets are::
# continued
@commands.command()
async def hunger(self, ctx, pet_name: str):
try:
hunger = await self.conf.user(ctx.author).pets.get_raw(pet_name, 'hunger')
except KeyError:
# Remember, this is thrown if something in the provided identifiers
# is not found in the saved data or the defaults.
await ctx.send("You don't own that pet!")
return
await ctx.send("Your pet has {}/100 hunger".format(hunger))
We're responsible pet owners here, so we've also got to have a way to feed our pets::
# continued
@commands.command()
async def feed(self, ctx, pet_name: str, food: int):
# This is a bit more complicated because we need to check if the pet is
# owned first.
try:
pet = await self.conf.user(ctx.author).pets.get_raw(pet_name)
except KeyError:
# If the given pet name doesn't exist in our data
await ctx.send("You don't own that pet!")
return
hunger = pet.get("hunger")
# Determine the new hunger and make sure it doesn't go negative
new_hunger = max(hunger - food, 0)
await self.conf.user(ctx.author).pets.set_raw(
pet_name, 'hunger', value=new_hunger
)
# We could accomplish the same thing a slightly different way
await self.conf.user(ctx.author).pets.get_attr(pet_name).hunger.set(new_hunger)
await ctx.send("Your pet is now at {}/100 hunger!".format(new_hunger)
*************
V2 Data Usage
*************
There has been much conversation on how to bring V2 data into V3 and, officially, we recommend that cog developers
make use of the public interface in Config (using the categories as described in these docs) rather than simply
copying and pasting your V2 data into V3. Using Config as recommended will result in a much better experience for
you in the long run and will simplify cog creation and maintenance.
However.
We realize that many of our cog creators have expressed disinterest in writing converters for V2 to V3 style data.
As a result we have opened up config to take standard V2 data and allow cog developers to manipulate it in V3 in
much the same way they would in V2. The following examples will demonstrate how to accomplish this.
.. warning::
By following this method to use V2 data in V3 you may be at risk of data corruption if your cog is used on a bot
with multiple shards. USE AT YOUR OWN RISK.
.. code-block:: python
from redbot.core import Config
class ExampleCog:
def __init__(self):
self.conf = Config.get_conf(self, 1234567890)
self.data = {}
async def load_data(self):
self.data = await self.conf.custom("V2", "V2").all()
async def save_data(self):
await self.conf.custom("V2", "V2").set(self.data)
async def setup(bot):
cog = ExampleCog()
await cog.load_data()
bot.add_cog(cog)
*************
API Reference
*************
.. important::
Before we begin with the nitty gritty API Reference, you should know that there are tons of working code examples
inside the bot itself! Simply take a peek inside of the :code:`tests/core/test_config.py` file for examples of using
Config in all kinds of ways.
.. automodule:: redbot.core.config
Config
^^^^^^
.. autoclass:: Config
:members:
Group
^^^^^
.. autoclass:: Group
:members:
:special-members:
Value
^^^^^
.. autoclass:: Value
:members:
:special-members: __call__
****************
Driver Reference
****************
.. automodule:: redbot.core.drivers
:members:
Base Driver
^^^^^^^^^^^
.. autoclass:: redbot.core.drivers.red_base.BaseDriver
:members:
JSON Driver
^^^^^^^^^^^
.. autoclass:: redbot.core.drivers.red_json.JSON
:members:
Mongo Driver
^^^^^^^^^^^^
.. autoclass:: redbot.core.drivers.red_mongo.Mongo
:members:
-10
View File
@@ -1,10 +0,0 @@
.. red invocation context documentation
==========================
Command Invocation Context
==========================
.. automodule:: redbot.core.context
.. autoclass:: redbot.core.RedContext
:members:
-11
View File
@@ -1,11 +0,0 @@
.. data manager docs
============
Data Manager
============
Data manager is a module that handles all the information necessary to bootstrap
the bot into a state where more abstract data management systems can take over.
.. automodule:: redbot.core.data_manager
:members:
-76
View File
@@ -1,76 +0,0 @@
.. downloader framework reference
Downloader Framework
====================
Info.json
*********
The info.json file may exist inside every package folder in the repo,
it is optional however. This string describes the valid keys within
an info file (and maybe how the Downloader cog uses them).
KEYS (case sensitive):
- ``author`` (list of strings) - list of names of authors of the cog
- ``bot_version`` (list of integer) - Min version number of Red in the format ``(MAJOR, MINOR, PATCH)``
- ``description`` (string) - A long description of the cog that appears when a user executes ```!cog info``.
- ``hidden`` (bool) - Determines if a cog is available for install.
- ``install_msg`` (string) - The message that gets displayed when a cog is installed
- ``required_cogs`` (map of cogname to repo URL) - A map of required cogs that this cog depends on.
Downloader will not deal with this functionality but it may be useful for other cogs.
- ``requirements`` (list of strings) - list of required libraries that are
passed to pip on cog install. ``SHARED_LIBRARIES`` do NOT go in this
list.
- ``short`` (string) - A short description of the cog that appears when
a user executes `!cog list`
- ``tags`` (list of strings) - A list of strings that are related to the
functionality of the cog. Used to aid in searching.
- ``type`` (string) - Optional, defaults to ``COG``. Must be either ``COG`` or
``SHARED_LIBRARY``. If ``SHARED_LIBRARY`` then ``hidden`` will be ``True``.
API Reference
*************
.. automodule:: redbot.cogs.downloader.json_mixins
.. autoclass RepoJSONMixin
:members
.. automodule:: redbot.cogs.downloader.installable
Installable
^^^^^^^^^^^
.. autoclass:: Installable
:members:
.. automodule:: redbot.cogs.downloader.repo_manager
Repo
^^^^
.. autoclass:: Repo
:members:
Repo Manager
^^^^^^^^^^^^
.. autoclass:: RepoManager
:members:
Exceptions
^^^^^^^^^^
.. automodule:: redbot.cogs.downloader.errors
:members:
-12
View File
@@ -1,12 +0,0 @@
.. framework events list
=============
Custom Events
=============
RPC Server
^^^^^^^^^^
.. py:method:: Red.on_shutdown()
Dispatched when the bot begins it's shutdown procedures.
-54
View File
@@ -1,54 +0,0 @@
.. i18n framework reference
.. role:: python(code)
:language: python
==============================
Internationalization Framework
==============================
-----------
Basic Usage
-----------
.. code-block:: python
from discord.ext import commands
from redbot.core.i18n import CogI18n
_ = CogI18n("ExampleCog", __file__)
class ExampleCog:
"""description"""
@commands.command()
async def mycom(self, ctx):
"""command description"""
await ctx.send(_("This is a test command"))
--------
Tutorial
--------
After making your cog, generate a :code:`messages.pot` file
The process of generating this will depend on the operating system
you are using
In a command prompt in your cog's package (where yourcog.py is),
create a directory called "locales".
Then do one of the following:
Windows: :code:`python <your python install path>\Tools\i18n\pygettext.py -n -p locales`
Mac: ?
Linux: :code:`pygettext3 -n -p locales`
This will generate a messages.pot file with strings to be translated
-------------
API Reference
-------------
.. automodule:: redbot.core.i18n
-95
View File
@@ -1,95 +0,0 @@
.. V3 Mod log
.. role:: python(code)
:language: python
=======
Mod log
=======
Mod log has now been separated from Mod for V3.
***********
Basic Usage
***********
.. code-block:: python
from redbot.core import modlog
import discord
class MyCog:
@commands.command()
@checks.admin_or_permissions(ban_members=True)
async def ban(self, ctx, user: discord.Member, reason: str=None):
await ctx.guild.ban(user)
case = modlog.create_case(
ctx.guild, ctx.message.created_at, "ban", user,
ctx.author, reason, until=None, channel=None
)
await ctx.send("Done. It was about time.")
**********************
Registering Case types
**********************
To register a single case type:
.. code-block:: python
from redbot.core import modlog
import discord
class MyCog:
def __init__(self, bot):
ban_case = {
"name": "ban",
"default_setting": True,
"image": ":hammer:",
"case_str": "Ban",
"audit_type": "ban"
}
modlog.register_casetype(**ban_case)
To register multiple case types:
.. code-block:: python
from redbot.core import modlog
import discord
class MyCog:
def __init__(self, bot):
new_types = [
{
"name": "ban",
"default_setting": True,
"image": ":hammer:",
"case_str": "Ban",
"audit_type": "ban"
},
{
"name": "kick",
"default_setting": True,
"image": ":boot:",
"case_str": "Kick",
"audit_type": "kick"
}
]
modlog.register_casetypes(new_types)
.. important::
Image should be the emoji you want to represent your case type with.
*************
API Reference
*************
Mod log
=======
.. automodule:: redbot.core.modlog
:members:
-8
View File
@@ -1,8 +0,0 @@
.. rpc docs
===
RPC
===
.. automodule:: redbot.core.rpc
:members:
-41
View File
@@ -1,41 +0,0 @@
.. red's core utils documentation
=================
Utility Functions
=================
Chat Formatting
===============
.. automodule:: redbot.core.utils.chat_formatting
:members:
Embed Helpers
=============
.. automodule:: redbot.core.utils.embed
:members:
Menu Helpers
============
.. automodule:: redbot.core.utils.menus
:members:
Mod Helpers
===========
.. automodule:: redbot.core.utils.mod
:members:
V2 Data Conversion
==================
.. automodule:: redbot.core.utils.data_converter
:members: DataConverter
Tunnel
======
.. automodule:: redbot.core.utils.tunnel
:members: Tunnel
-95
View File
@@ -1,95 +0,0 @@
.. Making cogs for V3
.. role:: python(code)
:language: python
====================
Creating cogs for V3
====================
This guide serves as a tutorial on creating cogs for Red V3.
It will cover the basics of setting up a package for your
cog and the basics of setting up the file structure. We will
also point you towards some further resources that may assist
you in the process.
---------------
Getting started
---------------
To start off, be sure that you have installed Python 3.5 or higher (if you
are on Windows, stick with 3.5). Open a terminal or command prompt and type
:code:`pip install --process-dependency-links -U git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=redbot[test]`
(note that if you get an error with this, try again but put :code:`python -m` in front of the command
This will install the latest version of V3.
--------------------
Setting up a package
--------------------
To set up a package, we would just need to create a new folder.
This should be named whatever you want the cog to be named (for
the purposes of this example, we'll call this :code:`mycog`).
In this folder, create three files: :code:`__init__.py`,
:code:`mycog.py`, and :code:`info.json`. Open the folder in
a text editor or IDE (examples include `Sublime Text 3 <https://www.sublimetext.com/>`_,
`Visual Studio Code <https://code.visualstudio.com/>`_, `Atom <https://atom.io/>`_, and
`PyCharm <http://www.jetbrains.com/pycharm/>`_).
--------------
Creating a cog
--------------
With your package opened in a text editor or IDE, open :code:`mycog.py`.
In that file, place the following code:
.. code-block:: python
from discord.ext import commands
class Mycog:
"""My custom cog"""
@commands.command()
async def mycom(self, ctx):
"""This does stuff!"""
# Your code will go here
await ctx.send("I can do stuff!")
Open :code:`__init__.py`. In that file, place the following:
.. code-block:: python
from .mycog import Mycog
def setup(bot):
bot.add_cog(Mycog())
Make sure that both files are saved.
----------------
Testing your cog
----------------
To test your cog, you will need a running instance of V3.
Assuming you installed V3 as outlined above, run :code:`redbot-setup`
and provide the requested information. Once that's done, run Red
by doing :code:`redbot <instance name> --dev` to start Red.
Complete the inital setup by providing a valid token and setting a
prefix. Once the bot has started up, use the link provided in the
console to add it to a server (note that you must have the
:code:`Manage Server` (or :code:`Administrator`) permission to add bots
to a server). Once it's been added to a server, find the full path
to the directory where your cog package is located. In Discord, do
:code:`[p]addpath <path_to_folder_containing_package>`, then do
:code:`[p]load mycog`. Once the cog is loaded, do :code:`[p]mycom`
The bot should respond with :code:`I can do stuff!`. If it did, you
have successfully created a cog!
--------------------
Additional resources
--------------------
Be sure to check out the :doc:`/guide_migration` for some resources
on developing cogs for V3. This will also cover differences between V2 and V3 for
those who developed cogs for V2.
-154
View File
@@ -1,154 +0,0 @@
.. Converting Data from a V2 cog
.. role:: python(code)
:language: python
============================
Importing Data From a V2 Cog
============================
This guide serves as a tutorial on using the DataConverter class
to import settings from a V2 cog.
------------------
Things you'll need
------------------
1. The path where each file holding related settings in v2 is
2. A conversion function to take the data and transform it to conform to Config
-----------------------
Getting your file paths
-----------------------
You should probably not try to find the files manually.
Asking the user for the base install path and using a relative path to where the
data should be, then testing that the file exists there is safer. This is especially
True if your cog has multiple settings files
Example
.. code-block:: python
from discord.ext import commands
from pathlib import Path
@commands.command(name="filefinder")
async def file_finding_command(self, ctx, filepath):
"""
this finds a file based on a user provided input and a known relative path
"""
base_path = Path(filepath)
fp = base_path / 'data' / 'mycog' / 'settings.json'
if not fp.is_file():
pass
# fail, prompting user
else:
pass
# do something with the file
---------------
Converting data
---------------
Once you've gotten your v2 settings file, you'll want to be able to import it
There are a couple options available depending on how you would like to convert
the data.
The first one takes a data path, and a conversion function and does the rest for you.
This is great for simple data that just needs to quickly be imported without much
modification.
Here's an example of that in use:
.. code-block:: python
from pathlib import Path
from discord.ext import commands
from redbot.core.utils.data_converter import DataConverter as dc
from redbot.core.config import Config
...
async def import_v2(self, file_path: Path):
"""
to be called from a command limited to owner
This should be a coroutine as the convert function will
need to be awaited
"""
# First we give the converter our cog's Config instance.
converter = dc(self.config)
# next we design a way to get all of the data into Config's internal
# format. This should be a generator, but you can also return a single
# list with identical results outside of memory usage
def conversion_spec(v2data):
for guild_id in v2.data.keys():
yield {(Config.GUILD, guild_id): {('blacklisted',): True}}
# This is yielding a dictionary that is designed for config's set_raw.
# The keys should be a tuple of Config scopes + the needed Identifiers. The
# values should be another dictionary whose keys are tuples representing
# config settings, the value should be the value to set for that.
# Then we pass the file and the conversion function
await converter.convert(file_path, conversion_spec)
# From here, our data should be imported
You can also choose to convert all of your data and pass it as a single dict
This can be useful if you want finer control over the dataconversion or want to
preserve any data from v3 that may share the same entry and set it aside to prompt
a user
.. code-block:: python
from pathlib import Path
from discord.ext import commands
from redbot.core.utils.data_converter import DataConverter as dc
from redbot.core.config import Config
...
await dc(config_instance).dict_import(some_processed_dict)
The format of the items of the dict is the same as in the above example
-----------------------------------
Config Scopes and their Identifiers
-----------------------------------
This section is provided as a quick reference for the identifiers for default
scopes available in Config. This does not cover usage of custom scopes, though the
data converter is compatible with those as well.
Global::
:code:`(Config.GLOBAL,)`
Guild::
:code:`(Config.GUILD, guild_id)`
Channel::
:code:`(Config.CHANNEL, channel_id)`
User::
:code:`(Config.USER, user_id)`
Member::
:code:`(Config.MEMBER, guild_id, user_id)`
Role::
:code:`(Config.ROLE, role_id)`
-----------------------------
More information and Examples
-----------------------------
For a more in depth look at how all of these commands function
You may want to take a look at how core data is being imported
:code:`redbot/cogs/dataconverter/core_specs.py`
-56
View File
@@ -1,56 +0,0 @@
.. V3 Migration Guide
.. role:: python(code)
:language: python
====================
Migrating Cogs to V3
====================
First, be sure to read `discord.py's migration guide <http://discordpy.readthedocs.io/en/rewrite/migrating.html>`_
as that covers all of the changes to discord.py that will affect the migration process
----------------
Red as a package
----------------
V3 makes Red a package that is installed with :code:`pip`. Please
keep this in mind when writing cogs as this affects how imports
should be done (for example, to import :code:`pagify` in V2, one
would do :code:`from .utils.chat_formatting import pagify`; in
V3, this becomes :code:`from redbot.core.utils.chat_formatting import pagify`)
----------------
Cogs as packages
----------------
V3 makes cogs into packages. See :doc:`/guide_cog_creation`
for more on how to create packages for V3.
------
Config
------
Config is V3's replacement for :code:`dataIO`. Instead of fiddling with
creating config directories and config files as was done in V2, V3's
Config handles that whilst allowing for easy storage of settings on a
per-server/member/user/role/channel or global basis. Be sure to check
out :doc:`/framework_config` for the API docs for Config as well as a
tutorial on using Config.
----
Bank
----
Bank in V3 has been split out from Economy. V3 introduces the ability
to have a global bank as well as the ability to change the bank name
and the name of the currency. Be sure to checkout :doc:`/framework_bank`
for more on Bank
-------
Mod Log
-------
V3 introduces Mod Log as an API, thus allowing for cogs to add custom case
types that will appear in a server's mod log channel. Be sure to checkout
:doc:`/framework_modlog` for more on Mod Log`
-56
View File
@@ -1,56 +0,0 @@
.. Red - Discord Bot documentation master file, created by
sphinx-quickstart on Thu Aug 10 23:18:25 2017.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Red - Discord Bot's documentation!
=============================================
.. toctree::
:maxdepth: 1
:caption: Installation Guides:
install_windows
install_mac
install_ubuntu
install_debian
install_centos
install_arch
install_raspbian
cog_dataconverter
autostart_systemd
.. toctree::
:maxdepth: 2
:caption: Cog Reference:
cog_downloader
.. toctree::
:maxdepth: 2
:caption: Red Development Framework Reference:
guide_migration
guide_cog_creation
guide_data_conversion
framework_bank
framework_bot
framework_cogmanager
framework_config
framework_context
framework_datamanager
framework_downloader
framework_events
framework_i18n
framework_modlog
framework_rpc
framework_utils
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
-55
View File
@@ -1,55 +0,0 @@
.. arch install guide
==============================
Installing Red on Arch Linux
==============================
.. warning:: For safety reasons, DO NOT install Red with a root user. Instead, make a new one.
:code:`https://wiki.archlinux.org/index.php/Users_and_groups`
-------------------------------
Installing the pre-requirements
-------------------------------
.. code-block:: none
sudo pacman -Syu python-pip git base-devel jre8-openjdk
------------------
Installing the bot
------------------
To install without audio:
:code:`pip3 install -U --process-dependency-links red-discordbot --user`
To install with audio:
:code:`pip3 install -U --process-dependency-links red-discordbot[voice] --user`
To install the development version (without audio):
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot --user`
To install the development version (with audio):
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice] --user`
------------------------
Setting up your instance
------------------------
Run :code:`redbot-setup` and follow the prompts. It will ask first for where you want to
store the data (the default is :code:`~/.local/share/Red-DiscordBot`) and will then ask
for confirmation of that selection. Next, it will ask you to choose your storage backend
(the default here is JSON). It will then ask for a name for your instance. This can be
anything as long as it does not contain spaces; however, keep in mind that this is the
name you will use to run your bot, and so it should be something you can remember.
-----------
Running Red
-----------
Run :code:`redbot <your instance name>` and run through the initial setup. This will ask for
your token and a prefix.
-56
View File
@@ -1,56 +0,0 @@
.. centos install guide
==========================
Installing Red on CentOS 7
==========================
.. warning:: For safety reasons, DO NOT install Red with a root user. Instead, `make a new one <https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Step_by_Step_Guide/s1-starting-create-account.html>`_.
---------------------------
Installing pre-requirements
---------------------------
.. code-block:: none
yum -y groupinstall development
yum -y install https://centos7.iuscommunity.org/ius-release.rpm
yum -y install yum-utils wget which python35u python35u-pip python35u-devel openssl-devel libffi-devel git java-1.8.0-openjdk
sh -c "$(wget https://gist.githubusercontent.com/mustafaturan/7053900/raw/27f4c8bad3ee2bb0027a1a52dc8501bf1e53b270/latest-ffmpeg-centos6.sh -O -)"
--------------
Installing Red
--------------
Without audio:
:code:`pip3 install -U --process-dependency-links red-discordbot --user`
With audio:
:code:`pip3 install -U --process-dependency-links red-discordbot[voice] --user`
To install the development version (without audio):
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot --user`
To install the development version (with audio):
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice] --user`
----------------------
Setting up an instance
----------------------
Run :code:`redbot-setup` and follow the prompts. It will ask first for where you want to
store the data (the default is :code:`~/.local/share/Red-DiscordBot`) and will then ask
for confirmation of that selection. Next, it will ask you to choose your storage backend
(the default here is JSON). It will then ask for a name for your instance. This can be
anything as long as it does not contain spaces; however, keep in mind that this is the
name you will use to run your bot, and so it should be something you can remember.
-----------
Running Red
-----------
Run :code:`redbot <your instance name>` and run through the initial setup. This will ask for
your token and a prefix.
-55
View File
@@ -1,55 +0,0 @@
.. debian install guide
================================
Installing Red on Debian Stretch
================================
.. warning:: For safety reasons, DO NOT install Red with a root user. Instead, `make a new one <https://manpages.debian.org/stretch/adduser/adduser.8.en.html>`_.
---------------------------
Installing pre-requirements
---------------------------
.. code-block:: none
echo "deb http://httpredir.debian.org/debian stretch-backports main contrib non-free" >> /etc/apt/sources.list
apt-get update
apt-get install python3.5-dev python3-pip build-essential libssl-dev libffi-dev git unzip default-jre -y
------------------
Installing the bot
------------------
To install without audio:
:code:`pip3 install -U --process-dependency-links red-discordbot`
To install with audio:
:code:`pip3 install -U --process-dependency-links red-discordbot[voice]`
To install the development version (without audio):
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot`
To install the development version (with audio):
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice]`
------------------------
Setting up your instance
------------------------
Run :code:`redbot-setup` and follow the prompts. It will ask first for where you want to
store the data (the default is :code:`~/.local/share/Red-DiscordBot`) and will then ask
for confirmation of that selection. Next, it will ask you to choose your storage backend
(the default here is JSON). It will then ask for a name for your instance. This can be
anything as long as it does not contain spaces; however, keep in mind that this is the
name you will use to run your bot, and so it should be something you can remember.
-----------
Running Red
-----------
Run :code:`redbot <your instance name>` and run through the initial setup. This will ask for
your token and a prefix.
-53
View File
@@ -1,53 +0,0 @@
.. mac install guide
=====================
Installing Red on Mac
=====================
---------------------------
Installing pre-requirements
---------------------------
* Install Brew
* In Finder or Spotlight, search for and open terminal. In the window that will open, paste this:
:code:`/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"`
and press enter.
* After the installation, install the required packages by pasting the commands and pressing enter, one-by-one:
* :code:`brew install python3 --with-brewed-openssl`
* :code:`brew install git`
* :code:`brew tap caskroom/versions`
* :code:`brew cask install java8`
--------------
Installing Red
--------------
Without audio:
:code:`pip3 install -U --process-dependency-links red-discordbot`
With audio:
:code:`pip3 install -U --process-dependency-links red-discordbot[voice]`
To install the development version (without audio):
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot`
To install the development version (with audio):
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice]`
----------------------
Setting up an instance
----------------------
To set up an instance, run :code:`redbot-setup` and follow the steps there, providing the requested information
or accepting the defaults. Keep in mind that the instance name will be the one you use when running the bot, so
make it something you can remember
-----------
Running Red
-----------
Run :code:`redbot <your instance name>` and go through the initial setup (it will ask for the token and a prefix).
-56
View File
@@ -1,56 +0,0 @@
.. raspbian install guide
==================================
Installing Red on Raspbian Stretch
==================================
.. warning:: For safety reasons, DO NOT install Red with a root user. Instead, `make a new one <https://www.raspberrypi.org/documentation/linux/usage/users.md>`_.
---------------------------
Installing pre-requirements
---------------------------
.. code-block:: none
sudo apt-get install python3.5-dev python3-pip build-essential libssl-dev libffi-dev git unzip default-jre -y
--------------
Installing Red
--------------
Without audio:
:code:`pip3 install -U --process-dependency-links red-discordbot --user`
With audio:
:code:`pip3 install -U --process-dependency-links red-discordbot[voice] --user`
To install the development version (without audio):
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot --user`
To install the development version (with audio):
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice] --user`
----------------------
Setting up an instance
----------------------
Run :code:`redbot-setup` and follow the prompts. It will ask first for where you want to
store the data (the default is :code:`~/.local/share/Red-DiscordBot`) and will then ask
for confirmation of that selection. Next, it will ask you to choose your storage backend
(the default here is JSON). It will then ask for a name for your instance. This can be
anything as long as it does not contain spaces; however, keep in mind that this is the
name you will use to run your bot, and so it should be something you can remember.
-----------
Running Red
-----------
Run :code:`redbot <your instance name>` and run through the initial setup. This will ask for
your token and a prefix.
.. warning:: Audio will not work on Raspberry Pi's **below** 2B. This is a CPU problem and *cannot* be fixed.
-54
View File
@@ -1,54 +0,0 @@
.. ubuntu install guide
==============================
Installing Red on Ubuntu 16.04
==============================
.. warning:: For safety reasons, DO NOT install Red with a root user. Instead, `make a new one <http://manpages.ubuntu.com/manpages/artful/man8/adduser.8.html>`_.
-------------------------------
Installing the pre-requirements
-------------------------------
.. code-block:: none
sudo apt install python3.5-dev python3-pip build-essential libssl-dev libffi-dev git unzip default-jre -y
------------------
Installing the bot
------------------
To install without audio:
:code:`pip3 install -U --process-dependency-links red-discordbot --user`
To install with audio:
:code:`pip3 install -U --process-dependency-links red-discordbot[voice] --user`
To install the development version (without audio):
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot --user`
To install the development version (with audio):
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice] --user`
------------------------
Setting up your instance
------------------------
Run :code:`redbot-setup` and follow the prompts. It will ask first for where you want to
store the data (the default is :code:`~/.local/share/Red-DiscordBot`) and will then ask
for confirmation of that selection. Next, it will ask you to choose your storage backend
(the default here is JSON). It will then ask for a name for your instance. This can be
anything as long as it does not contain spaces; however, keep in mind that this is the
name you will use to run your bot, and so it should be something you can remember.
-----------
Running Red
-----------
Run :code:`redbot <your instance name>` and run through the initial setup. This will ask for
your token and a prefix.
-47
View File
@@ -1,47 +0,0 @@
.. windows installation docs
=========================
Installing Red on Windows
=========================
---------------
Needed Software
---------------
* `Python <https://python.org/downloads/>`_ - Red needs at least Python 3.5
.. attention:: Please note that 3.6 has issues on some versions of Windows.
If you try using Red with 3.6 and experience issues, uninstall
Python 3.6 and install the latest version of Python 3.5
.. note:: Please make sure that the box to add Python to PATH is CHECKED, otherwise
you may run into issues when trying to run Red
* `Git <https://git-scm.com/download/win>`_
.. attention:: Please choose the option to "Run Git from the Windows Command Prompt" in Git's setup
* `Java <https://java.com/en/download/manual.jsp>`_ - needed for Audio
.. attention:: Please choose the "Windows Online" installer
--------------
Installing Red
--------------
1. Open a command prompt (open Start, search for "command prompt", then click it)
2. Run the appropriate command, depending on if you want audio or not
* No audio: :code:`python -m pip install -U --process-dependency-links Red-DiscordBot`
* Audio: :code:`python -m pip install -U --process-dependency-links Red-DiscordBot[voice]`
* Development version (without audio): :code:`python -m pip install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot`
* Development version (with audio): :code:`python -m pip install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice]`
3. Once that has completed, run :code:`redbot-setup` to set up your instance
* This will set the location where data will be stored, as well as your
storage backend and the name of the instance (which will be used for
running the bot)
4. Once done setting up the instance, run :code:`redbot <your instance name>` to run Red.
It will walk through the initial setup, asking for your token and a prefix
-36
View File
@@ -1,36 +0,0 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=python -msphinx
)
set SOURCEDIR=.
set BUILDDIR=_build
set SPHINXPROJ=Red-DiscordBot
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The Sphinx module was not found. Make sure you have Sphinx installed,
echo.then set the SPHINXBUILD environment variable to point to the full
echo.path of the 'sphinx-build' executable. Alternatively you may add the
echo.Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd
-4
View File
@@ -1,4 +0,0 @@
sphinx==1.6.5
sphinxcontrib-asyncio
sphinx_rtd_theme
git+https://github.com/Rapptz/discord.py@rewrite#egg=discord.py[voice]
+249
View File
@@ -0,0 +1,249 @@
from random import randint, choice
import time
import dataIO
client = None
settings = []
#words = dataIO.loadWords()
#anagram_sessions_timestamps = {}
anagram_sessions = []
payday_register = {}
PAYDAY_TIME = 300 # seconds between each payday
PAYDAY_CREDITS = 120 # credits received
def initialize():
global bank
bank = dataIO.fileIO("json/economy.json", "load")
def loadHelp():
global slot_help, economy_exp
if settings == []: return False #first run
slot_help = """ Slot machine payouts:
:two: :two: :six: Bet * 5000
:four_leaf_clover: :four_leaf_clover: :four_leaf_clover: +1000
:cherries: :cherries: :cherries: +800
:two: :six: Bet * 4
:cherries: :cherries: Bet * 3
Three symbols: +500
Two symbols: Bet * 2
You need an account to play. {0}register one.
Bet range: 5 - 100
""".format(settings["PREFIX"])
economy_exp = """ **Economy. Get rich and have fun with imaginary currency!**
{0}register - Register an account at the Twentysix bank
{0}balance - Check your balance
{0}slot help - Slot machine explanation
{0}slot [bid] - Play the slot machine
{0}payday - Type it every {1} seconds to receive some credits.
""".format(settings["PREFIX"], str(PAYDAY_TIME))
async def checkCommands(message):
p = settings["PREFIX"]
cmd = message.content
user = message.author
if cmd == p + "balance":
if accountCheck(user.id):
await client.send_message(message.channel, "{} `Your balance is: {}`".format(user.mention, str(checkBalance(user.id))))
else:
await client.send_message(message.channel, "{} `You don't have an account at the Twentysix bank. Type !register to open one.`".format(user.mention, str(checkBalance(user.id))))
elif cmd == p + "register":
await registerAccount(user, message)
elif cmd == p + "slot help":
await client.send_message(message.author, slot_help)
await client.send_message(message.channel, "{} `Check your DMs for the slot machine explanation.`".format(message.author.mention))
elif cmd.startswith(p + "slot"):
await slotMachineCheck(message)
elif cmd == p + "economy":
await client.send_message(message.author, economy_exp)
await client.send_message(message.channel, "{} `Check your DMs for the economy explanation.`".format(message.author.mention))
elif cmd == p + "challenge":
#isChallengeOngoing(message)
pass
elif cmd == p + "payday":
await payday(message)
async def registerAccount(user, message):
if user.id not in bank:
bank[user.id] = {"name" : user.name, "balance" : 100}
dataIO.fileIO("json/economy.json", "save", bank)
await client.send_message(message.channel, "{} `Account opened. Current balance: {}`".format(user.mention, str(checkBalance(user.id))))
else:
await client.send_message(message.channel, "{} `You already have an account at the Twentysix bank.`".format(user.mention))
def accountCheck(id):
if id in bank:
return True
else:
return False
def checkBalance(id):
if accountCheck(id):
return bank[id]["balance"]
else:
return False
def withdrawMoney(id, amount):
if accountCheck(id):
if bank[id]["balance"] >= int(amount):
bank[id]["balance"] = bank[id]["balance"] - int(amount)
dataIO.fileIO("json/economy.json", "save", bank)
else:
return False
else:
return False
def addMoney(id, amount):
if accountCheck(id):
bank[id]["balance"] = bank[id]["balance"] + int(amount)
dataIO.fileIO("json/economy.json", "save", bank)
else:
return False
def enoughMoney(id, amount):
if accountCheck(id):
if bank[id]["balance"] >= int(amount):
return True
else:
return False
else:
return False
async def isChallengeOngoing(message): #Work in progress
global anagram_sessions, anagram_sessions_timestamps
id = message.channel.id
for session in anagram_sessions:
if time.perf_counter() - session.started >= 600:
if session.done:
anagram_sessions.remove(session)
anagram_sessions.append(Anagram(message))
return True
else:
await client.send_message(message.channel, "{} `A challenge is already ongoing.`".format(message.author.mention))
return True
else:
await client.send_message(message.channel, "{} `You have to wait 10 minutes before each challenge.`".format(message.author.mention))
return True
anagram_sessions.append(Anagram(message))
async def payday(message):
id = message.author.id
if accountCheck(id):
if id in payday_register:
if abs(payday_register[id] - int(time.perf_counter())) >= PAYDAY_TIME:
addMoney(id, PAYDAY_CREDITS)
payday_register[id] = int(time.perf_counter())
await client.send_message(message.channel, "{} `Here, take some credits. Enjoy! (+{} credits!)`".format(message.author.mention, str(PAYDAY_CREDITS)))
else:
await client.send_message(message.channel, "{} `Too soon. You have to wait {} seconds between each payday.`".format(message.author.mention, str(PAYDAY_TIME)))
else:
payday_register[id] = int(time.perf_counter())
addMoney(id, PAYDAY_CREDITS)
await client.send_message(message.channel, "{} `Here, take some credits. Enjoy! (+{} credits!)`".format(message.author.mention, str(PAYDAY_CREDITS)))
else:
await client.send_message(message.channel, "{} `You need an account to receive credits. (!economy)`".format(message.author.mention))
###############SLOT##############
async def slotMachineCheck(message):
p = settings["PREFIX"]
msg = message.content.split()
if len(msg) == 2:
if msg[1].isdigit():
bid = int(msg[1])
if enoughMoney(message.author.id, bid):
if bid > 4 and bid < 101:
await slotMachine(message, bid)
else:
await client.send_message(message.channel, "{} `Bid must be between 5 and 100.`".format(message.author.mention))
else:
await client.send_message(message.channel, "{0} `You need an account with enough funds to play the slot machine. ({1}economy)`".format(message.author.mention, settings["PREFIX"]))
else:
await client.send_message(message.channel, "{} `".format(message.author.mention) + p + "slot [bid]`")
else:
await client.send_message(message.channel, "{} `".format(message.author.mention) + p + "slot [bid]`")
async def slotMachine(message, bid):
reel_pattern = [":cherries:", ":cookie:", ":two:", ":four_leaf_clover:", ":cyclone:", ":sunflower:", ":six:", ":mushroom:", ":heart:", ":snowflake:"]
padding_before = [":mushroom:", ":heart:", ":snowflake:"] # padding prevents index errors
padding_after = [":cherries:", ":cookie:", ":two:"]
reel = padding_before + reel_pattern + padding_after
reels = []
for i in range(0, 3):
n = randint(3,12)
reels.append([reel[n - 1], reel[n], reel[n + 1]])
line = [reels[0][1], reels[1][1], reels[2][1]]
display_reels = " " + reels[0][0] + " " + reels[1][0] + " " + reels[2][0] + "\n"
display_reels += ">" + reels[0][1] + " " + reels[1][1] + " " + reels[2][1] + "\n"
display_reels += " " + reels[0][2] + " " + reels[1][2] + " " + reels[2][2] + "\n"
if line[0] == ":two:" and line[1] == ":two:" and line[2] == ":six:":
bid = bid * 5000
await client.send_message(message.channel, "{}{} `226! Your bet is multiplied * 5000! {}!` ".format(display_reels, message.author.mention, str(bid)))
elif line[0] == ":four_leaf_clover:" and line[1] == ":four_leaf_clover:" and line[2] == ":four_leaf_clover:":
bid += 1000
await client.send_message(message.channel, "{}{} `Three FLC! +1000!` ".format(display_reels, message.author.mention))
elif line[0] == ":cherries:" and line[1] == ":cherries:" and line[2] == ":cherries:":
bid += 800
await client.send_message(message.channel, "{}{} `Three cherries! +800!` ".format(display_reels, message.author.mention))
elif line[0] == line[1] == line[2]:
bid += 500
await client.send_message(message.channel, "{}{} `Three symbols! +500!` ".format(display_reels, message.author.mention))
elif line[0] == ":two:" and line[1] == ":six:" or line[1] == ":two:" and line[2] == ":six:":
bid = bid * 4
await client.send_message(message.channel, "{}{} `26! Your bet is multiplied * 4! {}!` ".format(display_reels, message.author.mention, str(bid)))
elif line[0] == ":cherries:" and line[1] == ":cherries:" or line[1] == ":cherries:" and line[2] == ":cherries:":
bid = bid * 3
await client.send_message(message.channel, "{}{} `Two cherries! Your bet is multiplied * 3! {}!` ".format(display_reels, message.author.mention, str(bid)))
elif line[0] == line[1] or line[1] == line[2]:
bid = bid * 2
await client.send_message(message.channel, "{}{} `Two symbols! Your bet is multiplied * 2! {}!` ".format(display_reels, message.author.mention, str(bid)))
# elif line[0] == ":cherries:" or line[1] == ":cherries:" or line[2] == ":cherries:":
# await client.send_message(message.channel, "{}{} `Cherries! Your bet is safe!` ".format(display_reels, message.author.mention))
else:
await client.send_message(message.channel, "{}{} `Nothing! Lost bet.` ".format(display_reels, message.author.mention))
withdrawMoney(message.author.id, bid)
await client.send_message(message.channel, "`Credits left: {}`".format(str(checkBalance(message.author.id))))
return True
addMoney(message.author.id, bid)
await client.send_message(message.channel, "`Current credits: {}`".format(str(checkBalance(message.author.id))))
#######################################
############### ANAGRAM ###############
# Work in progress
class Anagram():
def __init__(self, message):
self.channel = message.channel
self.word = choice(words).lower()
self.anagram = list(self.word)
shuffle(self.anagram)
self.anagram = "".join(self.anagram)
self.started = int(time.perf_counter())
self.MAX_TIME = 60
self.done = False
def checkWord(self, message):
if time.perf_counter() - self.Atimestamp <= self.MAX_TIME:
msg = message.content.lower()
if msg.find(self.word) != -1:
pass
else:
self.gameOver()
async def gameOver(self):
self.done = True
try:
await client.send_message(self.channel, "`Anagram session over! No one guessed the word!`")
except:
pass
######################################
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
-33
View File
@@ -1,33 +0,0 @@
import subprocess
import os
import sys
def main():
interpreter = sys.executable
print(interpreter)
root_dir = os.getcwd()
cogs = [i for i in os.listdir("redbot/cogs") if os.path.isdir(os.path.join("redbot/cogs", i))]
for d in cogs:
if "locales" in os.listdir(os.path.join("redbot/cogs", d)):
os.chdir(os.path.join("redbot/cogs", d, "locales"))
if "regen_messages.py" not in os.listdir(os.getcwd()):
print("Directory 'locales' exists for {} but no 'regen_messages.py' is available!".format(d))
exit(1)
else:
print("Running 'regen_messages.py' for {}".format(d))
retval = subprocess.run([interpreter, "regen_messages.py"])
if retval.returncode != 0:
exit(1)
os.chdir(root_dir)
os.chdir("redbot/core/locales")
print("Running 'regen_messages.py' for core")
retval = subprocess.run([interpreter, "regen_messages.py"])
if retval.returncode != 0:
exit(1)
os.chdir(root_dir)
subprocess.run(["crowdin", "upload"])
if __name__ == "__main__":
main()
BIN
View File
Binary file not shown.
+2
View File
@@ -0,0 +1,2 @@
Insert your local playlists folders here. Every folder counts as a different playlist and can contain
.mp3 and .flac files. No spaces allowed in their filenames, use underscores instead.
+1
View File
@@ -0,0 +1 @@
{"playlist": ["https://www.youtube.com/watch?v=6sxnXO2RjVg", "https://www.youtube.com/watch?v=gj0Rz-uP4Mk", "https://www.youtube.com/watch?v=_izUd1S1BX0", "https://www.youtube.com/watch?v=K39qFmvbdww", "https://www.youtube.com/watch?v=ZFo8-JqzSCM", "https://www.youtube.com/watch?v=zD80CostTV0", "https://www.youtube.com/watch?v=mWADuNREJnY", "https://www.youtube.com/watch?v=xelUdXAvDVU", "https://www.youtube.com/watch?v=A2ptDgMOzc0", "https://www.youtube.com/watch?v=YwHrx0r0t2s", "https://www.youtube.com/watch?v=jqxNSvFMkag", "https://www.youtube.com/watch?v=gHgphqx1KT4", "https://www.youtube.com/watch?v=6sxnXO2RjVg", "https://www.youtube.com/watch?v=inb1z-qjxIU", "https://www.youtube.com/watch?v=fZZD8ckwLJA", "https://www.youtube.com/watch?v=xFn9V-VpkQ4", "https://www.youtube.com/watch?v=X7pjP_XkK4U", "https://www.youtube.com/watch?v=QPwPDDz-5Uo", "https://www.youtube.com/watch?v=6jmNe77vces", "https://www.youtube.com/watch?v=dga_ds1bJKg", "https://www.youtube.com/watch?v=oPmaVT-P5Ds", "https://www.youtube.com/watch?v=Ud_JZcC0tHI", "https://www.youtube.com/watch?v=35Cy7DUltYo", "https://www.youtube.com/watch?v=ZvmGLV_GE0M", "https://www.youtube.com/watch?v=7CXFXB4uknI", "https://www.youtube.com/watch?v=4pgbJaKemic", "https://www.youtube.com/watch?v=Jp6j5HJ-Cok", "https://www.youtube.com/watch?v=lzQ8GDBA8Is", "https://www.youtube.com/watch?v=Jt0mg8Z09SY", "https://www.youtube.com/watch?v=I6JZW7zMDfY", "https://www.youtube.com/watch?v=V2u-6XkB9O4", "https://www.youtube.com/watch?v=-ziSLGVQOSg", "https://www.youtube.com/watch?v=XFuAeGdUXQE", "https://www.youtube.com/watch?v=kHmoO_a4dDw", "https://www.youtube.com/watch?v=5XXe_5k_kno", "https://www.youtube.com/watch?v=Rk6YDzmqZ0I", "https://www.youtube.com/watch?v=5MgRt8zdr1I", "https://www.youtube.com/watch?v=50blPXs_F94", "https://www.youtube.com/watch?v=UrGLNtZ0rEg", "https://www.youtube.com/watch?v=atCwKBeq76w", "https://www.youtube.com/watch?v=QdfRZXsqDvc", "https://www.youtube.com/watch?v=lXgzQQ5XsHc", "https://www.youtube.com/watch?v=MAGoqMZRLB4", "https://www.youtube.com/watch?v=T1Ond-OwgU8", "https://www.youtube.com/watch?v=J-gkchrZIOU", "https://www.youtube.com/watch?v=3jrIK7YB0tE", "https://www.youtube.com/watch?v=RFxRTLmtsbE", "https://www.youtube.com/watch?v=0XSaKQlBZuE", "https://www.youtube.com/watch?v=cN-nfmrbvno", "https://www.youtube.com/watch?v=cUWyODR1_sA", "https://www.youtube.com/watch?v=uZ1a6hqxyJo", "https://www.youtube.com/watch?v=_sRkoZ-rbys", "https://www.youtube.com/watch?v=wdEibF6PXKY", "https://www.youtube.com/watch?v=KssCCe6KWcg", "https://www.youtube.com/watch?v=j3e_y9Bc7hs", "https://www.youtube.com/watch?v=QaP2vOdltP0", "https://www.youtube.com/watch?v=-n4kcvGS_Lk", "https://www.youtube.com/watch?v=e65ofKU6X6A", "https://www.youtube.com/watch?v=RDQsAvmPuT8", "https://www.youtube.com/watch?v=AFFaEgk-zeg", "https://www.youtube.com/watch?v=6aEx2xL37lw", "https://www.youtube.com/watch?v=H2GxBxeQGqA", "https://www.youtube.com/watch?v=Q_eE0NPArEY", "https://www.youtube.com/watch?v=WR8sxX0GoFo", "https://www.youtube.com/watch?v=Z_oIZzvSxeE", "https://www.youtube.com/watch?v=xL4oPjTACPo", "https://www.youtube.com/watch?v=aIz1cPfTRW4", "https://www.youtube.com/watch?v=DHG5-GxI_Es", "https://www.youtube.com/watch?v=VdqL8nbNbKg", "https://www.youtube.com/watch?v=mc7oGWgeA8s", "https://www.youtube.com/watch?v=clBEj47wjJM", "https://www.youtube.com/watch?v=Dsagy_qrjwc"], "author": "0"}
+1
View File
@@ -0,0 +1 @@
{"playlist": ["https://www.youtube.com/watch?v=fo-U2DVLt-I", "https://www.youtube.com/watch?v=2G5MPJ58yiM", "https://www.youtube.com/watch?v=-bQpAmqrUZ0", "https://www.youtube.com/watch?v=0I-zlOQFbJQ", "https://www.youtube.com/watch?v=4vcq3-CvUQo", "https://www.youtube.com/watch?v=0I-zlOQFbJQ", "https://www.youtube.com/watch?v=-bQpAmqrUZ0", "https://www.youtube.com/watch?v=2G5MPJ58yiM", "https://www.youtube.com/watch?v=fo-U2DVLt-I", "https://www.youtube.com/watch?v=gdOZ9TEeMT4", "https://www.youtube.com/watch?v=lxWeR2f_15Q", "https://www.youtube.com/watch?v=Kk9xQDYWtMo", "https://www.youtube.com/watch?v=SdKB8CT9eIM", "https://www.youtube.com/watch?v=HmyYe6P3zSk", "https://www.youtube.com/watch?v=CvCoE9Z_fy0", "https://www.youtube.com/watch?v=8vfbUXa7cF4", "https://www.youtube.com/watch?v=___m8qk9rKA", "https://www.youtube.com/watch?v=mu_37H-n_Nc", "https://www.youtube.com/watch?v=UCmiwCWqRYY", "https://www.youtube.com/watch?v=fyEJJkVDAAk"], "author": "0"}
+1
View File
@@ -0,0 +1 @@
{"playlist": ["https://www.youtube.com/watch?v=sRa1i1_K_-c", "https://www.youtube.com/watch?v=JHSyrs66vpk", "https://www.youtube.com/watch?v=Q-XPOwMztEA", "https://www.youtube.com/watch?v=VHufKcnlvzI", "https://www.youtube.com/watch?v=XINoGyLIkcE", "https://www.youtube.com/watch?v=wJkrgJI_7WY", "https://www.youtube.com/watch?v=CyJY5CFa1CE", "https://www.youtube.com/watch?v=DRKG19-hAlc", "https://www.youtube.com/watch?v=HJABO6w0EyA", "https://www.youtube.com/watch?v=r0noyvMPXpc", "https://www.youtube.com/watch?v=CYTEy3s-QRI", "https://www.youtube.com/watch?v=UJ6xBHmsGkk", "https://www.youtube.com/watch?v=RXfzu32HEOY", "https://www.youtube.com/watch?v=i7Yrtto5d_4", "https://www.youtube.com/watch?v=gIS593evoyU", "https://www.youtube.com/watch?v=9ztnSmWIDA0", "https://www.youtube.com/watch?v=nLP4ScjE1Wo", "https://www.youtube.com/watch?v=X5iiToqvBZ4"], "author": "0"}
+1
View File
@@ -0,0 +1 @@
{"playlist": ["https://www.youtube.com/watch?v=ezhFoRFTO1c&index=1&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=nznS-Tx2_ak&index=2&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=Op9IpbjV4yA&index=3&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=oHubvkHp5fc&index=4&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=9rN67kPp5tQ&index=5&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=3CCzW49z0hI&index=6&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=Z7GWyasxb5E&index=7&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=2Mahk4wS0XA&index=8&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=QaLF7Cqy-uA&index=9&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=H027APFs8vc&index=10&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=-jus1FrPILs&index=11&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=EAinJ8fVGGU&index=12&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=2H94C-MGM4M&index=13&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=raE7uP2L1Vo&index=14&list=PLA5F145C2D3E4A298", "https://www.youtube.com/watch?v=nCyh83oprvU&index=15&list=PLA5F145C2D3E4A298"], "author": "0"}
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"playlist": ["https://www.youtube.com/watch?v=gziaF9VT2D4", "https://www.youtube.com/watch?v=7Okz5qov7Go", "https://www.youtube.com/watch?v=olmgSyTtiwI", "https://www.youtube.com/watch?v=tQFMDOQXW30", "https://www.youtube.com/watch?v=Q4lN5HRjWCQ", "https://www.youtube.com/watch?v=UMlnE9QWma0", "https://www.youtube.com/watch?v=ix6V-l-ro1o", "https://www.youtube.com/watch?v=PdjYXcQPbig", "https://www.youtube.com/watch?v=e9mcNVTpovE", "https://www.youtube.com/watch?v=v3bAw8G-qQ4", "https://www.youtube.com/watch?v=WczTbnB0_lE", "https://www.youtube.com/watch?v=e05sBkIz2h0", "https://www.youtube.com/watch?v=fklAh1ncxng", "https://www.youtube.com/watch?v=t6Xwj1lVZFc", "https://www.youtube.com/watch?v=0IfjbF8aY4o", "https://www.youtube.com/watch?v=sLZ7RCxMCO4"], "author": "0"}
+1
View File
@@ -0,0 +1 @@
{"playlist": ["https://www.youtube.com/watch?v=_XDlWepXuaM", "https://www.youtube.com/watch?v=lJUq8jzU0CA", "https://www.youtube.com/watch?v=OD4hSJybyCY", "https://www.youtube.com/watch?v=g2GVOqG5jWs", "https://www.youtube.com/watch?v=kgOkwV5xX8w", "https://www.youtube.com/watch?v=r6g2Iz3vzgY", "https://www.youtube.com/watch?v=pPArO-OI_3U", "https://www.youtube.com/watch?v=VcLk3fQ3Zwg", "https://www.youtube.com/watch?v=8gJv_NdTyZ0", "https://www.youtube.com/watch?v=z1GJMJbZybQ", "https://www.youtube.com/watch?v=1Qye2uNicbY", "https://www.youtube.com/watch?v=9lrWx7-PiUM", "https://www.youtube.com/watch?v=DVzUAqbAaaw", "https://www.youtube.com/watch?v=ojwkRSGXkn8", "https://www.youtube.com/watch?v=gX89Y7AgoXw", "https://www.youtube.com/watch?v=Nz30L9NYFf8", "https://www.youtube.com/watch?v=DMjBnLN2_ME", "https://www.youtube.com/watch?v=58MZ8ECtPTw", "https://www.youtube.com/watch?v=hvN3zMPn4fk", "https://www.youtube.com/watch?v=Op8T7MltzbU", "https://www.youtube.com/watch?v=Kp9hIeC828o", "https://www.youtube.com/watch?v=eP9nD0TsqEI", "https://www.youtube.com/watch?v=7jKA8bKfIic", "https://www.youtube.com/watch?v=6OkQiVWIp_E", "https://www.youtube.com/watch?v=PemXuiZ0iAc", "https://www.youtube.com/watch?v=hXTT8ZkwJ_o", "https://www.youtube.com/watch?v=8dO4mV7fuhU", "https://www.youtube.com/watch?v=5K7Q409AWKk", "https://www.youtube.com/watch?v=Lqre-N_28Yo", "https://www.youtube.com/watch?v=1DD_NCM_RJs"], "author": "0"}
+1
View File
@@ -0,0 +1 @@
{"author": "0", "playlist": ["https://www.youtube.com/watch?v=cvaIgq5j2Q8", "https://www.youtube.com/watch?v=Q69_lnD6GhE", "https://www.youtube.com/watch?v=TEsJW9KXuOc", "https://www.youtube.com/watch?v=McfkDbjfllo", "https://www.youtube.com/watch?v=lN3psvKJNvQ", "https://www.youtube.com/watch?v=bOpLs6qfYoI", "https://www.youtube.com/watch?v=cd8e2ECUHL4", "https://www.youtube.com/watch?v=7DVGCs6kWmc", "https://www.youtube.com/watch?v=pUyjKFclkCY", "https://www.youtube.com/watch?v=G75WApUdYJ4", "https://www.youtube.com/watch?v=oSMCZ0Y1nUE", "https://www.youtube.com/watch?v=K8qLdz9GT-0", "https://www.youtube.com/watch?v=QYKFwX1l4Rw", "https://www.youtube.com/watch?v=GmbpUKp6J6M", "https://www.youtube.com/watch?v=FLzIEKz8F20", "https://www.youtube.com/watch?v=NSZFKDOs-yc", "https://www.youtube.com/watch?v=mdML5WPEhEY", "https://www.youtube.com/watch?v=gRdgASty-1g", "https://www.youtube.com/watch?v=zcI8_rLWk3g", "https://www.youtube.com/watch?v=rRh_d2qjavQ", "https://www.youtube.com/watch?v=afJnOSqbP8k", "https://www.youtube.com/watch?v=6xYaoyr0D6E", "https://www.youtube.com/watch?v=oV2lyc5UKXc", "https://www.youtube.com/watch?v=fzB-oRQiI-s", "https://www.youtube.com/watch?v=jSEnYAPEOEQ", "https://www.youtube.com/watch?v=AGWGmkouZxs", "https://www.youtube.com/watch?v=SByfHj_cBQ4", "https://www.youtube.com/watch?v=UQFrKtIFqd8", "https://www.youtube.com/watch?v=HYm3xJabxHw", "https://www.youtube.com/watch?v=mz3h93cH3Zo", "https://www.youtube.com/watch?v=cXWTFV8Z-i0", "https://www.youtube.com/watch?v=oedmZoHjlHE", "https://www.youtube.com/watch?v=x9WpVoAC3tk", "https://www.youtube.com/watch?v=SOg73IfyoFw", "https://www.youtube.com/watch?v=RAO1kWJdYz8", "https://www.youtube.com/watch?v=xkIytYlDD_o", "https://www.youtube.com/watch?v=c0mX-5q3mrY", "https://www.youtube.com/watch?v=OQktBoamgXc", "https://www.youtube.com/watch?v=7RGTFmF-brI", "https://www.youtube.com/watch?v=h2XTsWgN0CU", "https://www.youtube.com/watch?v=2yhhK_2HZzQ", "https://www.youtube.com/watch?v=jx5oOXZOiWc", "https://www.youtube.com/watch?v=Xh8uiKbT9_E", "https://www.youtube.com/watch?v=ksme1nbbTAc", "https://www.youtube.com/watch?v=cSpnJjM1H24", "https://www.youtube.com/watch?v=6_svEzbs15w", "https://www.youtube.com/watch?v=gbOuRQNwtN4", "https://www.youtube.com/watch?v=EWQpFKhEEgI", "https://www.youtube.com/watch?v=GpOv05A1nf0", "https://www.youtube.com/watch?v=cyW2ajAVyfA", "https://www.youtube.com/watch?v=R7IJC6nMons", "https://www.youtube.com/watch?v=bYlUbG01-wA", "https://www.youtube.com/watch?v=vu5Q5Fox2ng", "https://www.youtube.com/watch?v=9buluPWlkAA", "https://www.youtube.com/watch?v=hDNcUGd88Qo", "https://www.youtube.com/watch?v=w77inmTq04E", "https://www.youtube.com/watch?v=VUoH08wbZ9E", "https://www.youtube.com/watch?v=YxqwOq2hA-k", "https://www.youtube.com/watch?v=G8Gb1cwLO3s", "https://www.youtube.com/watch?v=EjoDnuoSDkg", "https://www.youtube.com/watch?v=lfwVMlBRlDY", "https://www.youtube.com/watch?v=bYDxqf2zR2Y", "https://www.youtube.com/watch?v=qbKz5nov1KU", "https://www.youtube.com/watch?v=ZMKWC3Hi8p0", "https://www.youtube.com/watch?v=wyNc0WtHw6I", "https://www.youtube.com/watch?v=19hhHW9C4FA", "https://www.youtube.com/watch?v=pUKmdDaYhL8", "https://www.youtube.com/watch?v=pkyLAWX5V30", "https://www.youtube.com/watch?v=oY1iMtBExOo", "https://www.youtube.com/watch?v=4ugZ7NMiW50", "https://www.youtube.com/watch?v=EPElX0cjm-w", "https://www.youtube.com/watch?v=535ONQFgu2M", "https://www.youtube.com/watch?v=O6NvsM49N6w", "https://www.youtube.com/watch?v=McRA3CKvJZ4", "https://www.youtube.com/watch?v=2pKAcywkr0s", "https://www.youtube.com/watch?v=OFDB9SV6ug8", "https://www.youtube.com/watch?v=tyaPqW0bO5M", "https://www.youtube.com/watch?v=eprDsre1tQo", "https://www.youtube.com/watch?v=vQMSdPgAj6Q", "https://www.youtube.com/watch?v=Tvj2Q--JMhA", "https://www.youtube.com/watch?v=b8cOZ6iJ5PY", "https://www.youtube.com/watch?v=-1-DE0lDATQ", "https://www.youtube.com/watch?v=wL-2Cu6zSNk", "https://www.youtube.com/watch?v=vjd5ndxjt-8", "https://www.youtube.com/watch?v=YTpgmqlX_OA", "https://www.youtube.com/watch?v=eUEtFvjrqMg", "https://www.youtube.com/watch?v=1zn-5YVG3Sw", "https://www.youtube.com/watch?v=oMuvGDUgLfw", "https://www.youtube.com/watch?v=bbDY5bRcZrw", "https://www.youtube.com/watch?v=-jcsoAO83X0", "https://www.youtube.com/watch?v=fU_Vm5dVHgc", "https://www.youtube.com/watch?v=-yShvzoWrsA", "https://www.youtube.com/watch?v=uI4Aj-KbhcY", "https://www.youtube.com/watch?v=TU-5jJnK_7o", "https://www.youtube.com/watch?v=rnP8JZkmN68", "https://www.youtube.com/watch?v=yOMkGjp_m1Q", "https://www.youtube.com/watch?v=NOgZ-XNOHhU", "https://www.youtube.com/watch?v=A2qJNZklnuQ", "https://www.youtube.com/watch?v=F0GcEI-R9mM", "https://www.youtube.com/watch?v=cON1VmHX1jE"]}
+1
View File
@@ -0,0 +1 @@
{"playlist": ["https://www.youtube.com/watch?v=nU263Ud3LM4", "https://www.youtube.com/watch?v=m1KVDI7vbEM", "https://www.youtube.com/watch?v=D0j9AOEhzO8", "https://www.youtube.com/watch?v=pjGgfZ8JkyA", "https://www.youtube.com/watch?v=PK1yjBgxgho", "https://www.youtube.com/watch?v=eQdQ3ngu0n8", "https://www.youtube.com/watch?v=jFEOKz9-Xv8", "https://www.youtube.com/watch?v=rxqHQ9nOZcc", "https://www.youtube.com/watch?v=opXXFAl8lkY", "https://www.youtube.com/watch?v=mo_CY0HcIws", "https://www.youtube.com/watch?v=m1ud5-glY6M", "https://www.youtube.com/watch?v=fzcCjDb65QI", "https://www.youtube.com/watch?v=fbcjFvXGXYQ", "https://www.youtube.com/watch?v=TWrq8rY47Oo", "https://www.youtube.com/watch?v=9_H9rnqeDDU", "https://www.youtube.com/watch?v=jHxPVXfMjk4", "https://www.youtube.com/watch?v=gOg1sj1abyw", "https://www.youtube.com/watch?v=kFNHlJ6yvEA", "https://www.youtube.com/watch?v=JWsLm7mND1k", "https://www.youtube.com/watch?v=JbCtVIDMEAs", "https://www.youtube.com/watch?v=j2qWM1cnLrg", "https://www.youtube.com/watch?v=XLuSY7jTBxg", "https://www.youtube.com/watch?v=X7gHzu7SBlw", "https://www.youtube.com/watch?v=aP0m-PJozWo", "https://www.youtube.com/watch?v=4MNAktk9ei8", "https://www.youtube.com/watch?v=2XjouKSkSeM", "https://www.youtube.com/watch?v=0d1ZdB_f8h4", "https://www.youtube.com/watch?v=7Wmk58-o_r8", "https://www.youtube.com/watch?v=S1-VyHIx_SY", "https://www.youtube.com/watch?v=YZdy9-4KiEo", "https://www.youtube.com/watch?v=OuSzXP-Hj_A", "https://www.youtube.com/watch?v=epwA8VIbEFo", "https://www.youtube.com/watch?v=JuqZTPyzHfg", "https://www.youtube.com/watch?v=2YodHq4iZFc", "https://www.youtube.com/watch?v=_a3hoWJDXSs", "https://www.youtube.com/watch?v=-1KBQTGSDFA", "https://www.youtube.com/watch?v=4P4b_YTNC7c", "https://www.youtube.com/watch?v=AOZL3kkCUBQ", "https://www.youtube.com/watch?v=ul-brw07gJo", "https://www.youtube.com/watch?v=pEsQi6GRwhM", "https://www.youtube.com/watch?v=SWZvaWzdgek", "https://www.youtube.com/watch?v=HA9Ws-_iCEw", "https://www.youtube.com/watch?v=zUfJaqFV0hk", "https://www.youtube.com/watch?v=vdSA6waSFs8", "https://www.youtube.com/watch?v=g76W944CXzo", "https://www.youtube.com/watch?v=HwpJnvadoIQ", "https://www.youtube.com/watch?v=2Hw597sv7ZM", "https://www.youtube.com/watch?v=9ts_foHlT_w", "https://www.youtube.com/watch?v=B4u0FAJIvwg", "https://www.youtube.com/watch?v=3A_pI3UuMn8", "https://www.youtube.com/watch?v=AZl1LFtUQNA", "https://www.youtube.com/watch?v=ERy3UlFxFoc", "https://www.youtube.com/watch?v=txzD9iHBu-w", "https://www.youtube.com/watch?v=eaK564p5ksc", "https://www.youtube.com/watch?v=H9bDN_aZvNI", "https://www.youtube.com/watch?v=Gv9jl_vGb-w", "https://www.youtube.com/watch?v=xLD4J-qYf8k", "https://www.youtube.com/watch?v=h9SFxVFKZw0", "https://www.youtube.com/watch?v=txzD9iHBu-w", "https://www.youtube.com/watch?v=eaK564p5ksc", "https://www.youtube.com/watch?v=H9bDN_aZvNI", "https://www.youtube.com/watch?v=Gv9jl_vGb-w", "https://www.youtube.com/watch?v=xLD4J-qYf8k", "https://www.youtube.com/watch?v=h9SFxVFKZw0", "https://www.youtube.com/watch?v=exG220Mur04"], "author": "0"}
+1
View File
@@ -0,0 +1 @@
{"playlist": ["https://www.youtube.com/watch?v=pfAuWjCXwnw", "https://www.youtube.com/watch?v=ToLBU-zJ2S0", "https://www.youtube.com/watch?v=Z-7OySB0Yb4", "https://www.youtube.com/watch?v=91jSk2G6Dr0", "https://www.youtube.com/watch?v=pbTgi_gLppQ", "https://www.youtube.com/watch?v=8keRZa7hAqM", "https://www.youtube.com/watch?v=XfHdXHqWZyE", "https://www.youtube.com/watch?v=NkYxsnWj8Ds", "https://www.youtube.com/watch?v=XSGxYnnwcLg", "https://www.youtube.com/watch?v=ieTtWb7oHIo", "https://www.youtube.com/watch?v=y2F1BL_p5jk", "https://www.youtube.com/watch?v=Waf_AcAfPWA", "https://www.youtube.com/watch?v=dcx3mzLySew", "https://www.youtube.com/watch?v=-VruEefJAHI", "https://www.youtube.com/watch?v=EUxNv_9Zxns", "https://www.youtube.com/watch?v=C3yP_-lOhzA", "https://www.youtube.com/watch?v=cpjh4_ReUCw", "https://www.youtube.com/watch?v=urmoWFQw4aE", "https://www.youtube.com/watch?v=TAzxVL-xWww", "https://www.youtube.com/watch?v=zve5kLOjITU", "https://www.youtube.com/watch?v=2QceNDYmbAo", "https://www.youtube.com/watch?v=DV8zA27UdVU", "https://www.youtube.com/watch?v=uPQMYfXLpKo"], "author": "0"}
+1
View File
@@ -0,0 +1 @@
{"playlist": ["https://www.youtube.com/watch?v=lG5aSZBAuPs", "https://www.youtube.com/watch?v=uf9WLPZK2AU", "https://www.youtube.com/watch?v=PMd9eYXT0mM", "https://www.youtube.com/watch?v=J3JNlHQ-hj8", "https://www.youtube.com/watch?v=d8Q5kzUlim8", "https://www.youtube.com/watch?v=6sQCATXFzsI", "https://www.youtube.com/watch?v=KrxJQAYdfXo", "https://www.youtube.com/watch?v=V18pa_VDw3I", "https://www.youtube.com/watch?v=h4dzCbjtyW8", "https://www.youtube.com/watch?v=Z_8zEMF3EaY", "https://www.youtube.com/watch?v=ODkX3x1SDHo", "https://www.youtube.com/watch?v=yV2Z62mSoOA", "https://www.youtube.com/watch?v=LgE7gqts_Kg", "https://www.youtube.com/watch?v=EizM69vZebg", "https://www.youtube.com/watch?v=fhOjNhRZ1Gc", "https://www.youtube.com/watch?v=ITjX9IOJdLA"], "author": "0"}
+551
View File
@@ -0,0 +1,551 @@
A bird in the hand is worth two in the bush
A chain is only as strong as its weakest link
A change is as good as a rest
A drowning man will clutch at a straw.
A fair day's work for a fair day's pay
A fool and his money are soon parted
A friend in need is a friend indeed
A golden key can open any door
A good beginning makes a good ending.
A good man is hard to find
A house divided against itself cannot stand
A house is not a home
A journey of a thousand miles begins with a single step
A leopard cannot change its spots
A little knowledge is a dangerous thing
A little of what you fancy does you good
A man who is his own lawyer has a fool for his client
A man with a hammer sees every problem as a nail
A miss is as good as a mile
A new broom sweeps clean, but an old one knows where the dirt is.
A nod is as good as a wink to a blind horse
A penny saved is a penny earned
A person is known by the company he keeps
A picture is worth a thousand words
A place for everything and everything in its place
A poor workman always blames his tools
A problem shared is a problem halved
A prophet is not recognized in his own land
A rising tide lifts all boats
A rolling stone gathers no moss
A soft answer turneth away wrath
A stitch in time saves nine
A swarm in May is worth a load of hay; a swarm in June is worth a silver spoon; but a swarm in July is not worth a fly.
A thing of beauty is a joy forever
A trouble shared is a trouble halved
A volunteer is worth twenty pressed men
A watched pot never boils
A woman's place is in the home
A man works from sun to sun but a woman's work is never done,
A word to the wise is enough,
Absence makes the heart grow fonder
Absolute power corrupts absolutely.
Accidents will happen (in the best-regulated families)
Actions speak louder than words.
Adversity makes strange bedfellows
All good things come to he who waits
All good things must come to an end,
All is grist that comes to the mill
All roads lead to Rome,
All that glitters is not gold,
All the world loves a lover
All things come to those who wait
All things must pass
All work and no play makes Jack a dull boy,
All you need is love
All is fair in love and war
All is for the best in the best of all possible worlds
All is well that ends well
An apple a day keeps the doctor away
An army marches on its stomach.
An Englishman's home is his castle
Another day, another dollar.
An ounce of prevention is worth a pound of cure
Any port in a storm,
Any publicity is good publicity
April showers bring forth May flowers,
As you make your bed, so you must lie upon it
As you sow so shall you reap
Ask a silly question and you will get a silly answer
Ask my companion if I be a thief
Ask no questions and hear no lies
Attack is the best form of defense
Bad news travels fast
Barking dogs seldom bite,
Beauty is in the eye of the beholder
Beauty is only skin deep,
Beggars should not be choosers,
Behind every great man, there is a great woman
Better late than never
Better safe than sorry
Better the Devil you know than the Devil you do not
Better to have loved and lost than never to have loved at all
Better to light one candle than to curse the darkness
Better to remain silent and be thought a fool than to speak and remove all doubt
Better wear out than rust out.
Beware of Greeks bearing gifts
Big fish eat little fish
Birds of a feather flock together
Blood is thicker than water
Boys will be boys
Brevity is the soul of wit
Business before pleasure
Caesar's wife must be above suspicion
Careless talk costs lives
Charity begins at home
Cheats never prosper
Children should be seen and not heard
Christmas comes but once a year
Cleanliness is next to godliness
Clothes make the man
Cold hands, warm heart
Comparisons are odious
Count your blessings
Courage is the measure of a Man, Beauty is the measure of a Woman
Cowards may die many times before their death
Crime does not pay
Cut your coat according to your cloth,
Curiosity killed the cat
Dead men tell no tales
Devil take the hindmost
Discretion is the better part of valour
Do as I say, not as I do
Do as you would be done by
Do unto others as you would have them do unto you
Do not bite the hand that feeds you
Do not burn your bridges behind you
Do not cast your pearls before swine
Do not cry over spilt milk
Do not change horses in midstream
Do not count your chickens before they are hatched
Do not cross the bridge till you come to it
Do not cut off your nose to spite your face
Do not keep a dog and bark yourself
Do not let the bastards grind you down
Do not look a gift horse in the mouth
Do not make a mountain of a mole hill
Do not meet troubles half-way
Do not put all your eggs in one basket
Do not put the cart before the horse
Do not put new wine into old bottles
Do not rock the boat
Do not spoil the ship for a ha'pworth of tar
Do not throw pearls to swine
Do not teach your Grandmother to suck eggs
Do not throw the baby out with the bathwater
Do not try to walk before you can crawl
Do not upset the apple-cart
Do not wash your dirty linen in public
Doubt is the beginning, not the end, of wisdom
Early to bed and early to rise, makes a man healthy, wealthy and wise
East is east, and west is west
East, west, home is best,
Easy come, easy go
Eat breakfast as a king, lunch as a merchant and supper as a beggar
Eat, drink and be merry, for tomorrow we die
Empty vessels make the most noise
Enough is as good as a feast
Enough is enough
Even a worm will turn
Every cloud has a silver lining
Every dog has his day
Every Jack has his Jill
Every little bit helps
Every man for himself, and the Devil take the hindmost
Every man has his price
Every picture tells a story
Every stick has two ends
Everybody wants to go to heaven but nobody wants to die
Everything comes to those who wait
Every tide has its ebb
Fact is stranger than fiction
Failing to plan is planning to fail
Faint heart never won fair lady
Fair exchange is no robbery
Faith will move mountains
Familiarity breeds contempt
Feed a cold and starve a fever
Fight fire with fire
Finders keepers, losers weepers
First come, first served
First impressions are the most lasting
First things first
Fish always stinks from the head downwards
Fish and guests smell after three days
Flattery will get you nowhere
Fools rush in where angels fear to tread
For want of a nail the shoe was lost; for want of a shoe the horse was lost; and for want of a horse the man was lost
Forewarned is forearmed
Fortune favours the brave
Genius is an infinite capacity for taking pains
Give a dog a bad name and hang him
Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime
Give a man rope enough and he will hang himself
Give credit where credit is due
Give him an inch and he will take a mile
God helps those who help themselves
Good fences make good neighbours
Good talk saves the food
Good things come to those who wait
Great minds think alike
Half a loaf is better than no bread
Handsome is as handsome does
Hard cases make bad law
Hard work never did anyone any harm
Haste makes waste
He that goes a-borrowing, goes a-sorrowing
He who can does, he who cannot, teaches
He who fights and runs away may live to fight another day
He who hesitates is lost
He who laughs last laughs best
He who lives by the sword shall die by the sword
He who loves the world as his body may be entrusted with the empire.
He who makes a beast out of himself gets rid of the pain of being a man
He who pays the piper calls the tune
He who knows does not speak. He who speaks does not know.
He who sups with the Devil should have a long spoon
Hell hath no fury like a woman scorned
Hindsight is always twenty-twenty
History repeats itself
Home is where the heart is
Honesty is the best policy
Hope springs eternal
Horses for courses
Hunger never knows the taste, sleep never knows the comfort
If anything can go wrong, it will
If a job is worth doing, it is worth doing well
If at first you do not succeed, try, try again
If God had meant us to fly, he would have given us wings
If ifs and ands were pots and pans, there would be no work for tinkers
When life gives you lemons, make lemonade
If the cap fits, wear it
If the mountain will not come to Mohammed, then Mohammed must go to the mountain
If we're not back by dawn, call the President.
If wealth is lost, nothing is lost. If health is lost, something is lost. If character is lost, everything is lost.
If wishes were horses, beggars would ride
If you're growing in Age,then you're nearing to the Graveyard
If you cannot be good, be careful
If you cannot beat them, join them
If you cannot stand the heat, get out of the kitchen
If you give a mouse a cookie, he'll always ask for a glass of milk
If you think that you know everything, then you're a Jack ass
If you lie down with dogs, you will get up with fleas
If you pay peanuts, you get monkeys
If you steal from one author, it is plagiarism; if you steal from many, it is research.
If you want a thing done well, do it yourself
If you have never seen the bottom of the tree, you cannot know how tall it stands
Imitation is the sincerest form of flattery
In for a penny, in for a pound
In the kingdom of the blind, the one eyed man is king
In the midst of life, we are in death
Into every life a little rain must fall
It goes without saying
It is all grist to the mill
It is an ill wind that blows no one any good
It is best to be on the safe side
It is better to give than to receive
It is better to have loved and lost than never to have loved at all
It is better to cultivate a Land with two Bulls, rather working under Boss who never gives Wage when asked
It is better to light a candle than curse the darkness
It is better to travel hopefully than to arrive
It is easy to be wise after the event
It is never too late
It is no use crying over spilt milk
It is no use locking the stable door after the horse has bolted
It is on
It is the early bird that gets the worm
It is the empty can that makes the most noise
It is the squeaky wheel that gets the grease
It never rains but it pours
It takes a thief to catch a thief
It needs a Hundred Lies to cover a Single Lie
It takes all sorts to make a world
It takes one to know one
It takes two to tango
I'm going to have to give you the pink slip
Jack of all trades, master of none
Jack of all trades, master of some
Judge not, that ye be not judged.
Keep your friends close and your enemies closer.
Trust in God and keep your powder dry
Kindness in words creates confidence. Kindness in thinking creates profoundness. Kindness in giving creates love.
Knowledge is power, guard it well.
Laugh before breakfast, cry before supper.
Laugh and the world laughs with you, weep and you weep alone
Laughter is the best medicine
Least said, soonest mended
Less is more
Let bygones be bygones
Let not the sun go down on your wrath
Let sleeping dogs lie
Let the buyer beware
Let the dead bury the dead
Let the punishment fit the crime
Let well alone
Let your hair down.
Life begins at forty
Life is not all beer and skittles
Life is what you make it
Lightning never strikes twice in the same place
Like father, like son,
Little pitchers have big ears
Little strokes fell great oaks
Little things please little minds
Live and let live
Live for today, for tomorrow never comes
Loose lips, sink ships
Look before you leap
Love is blind
Love of money is the root of all kinds of evil.
Love makes the world go around
Love will find a way
Make hay while the sun shines
Make love not war
Man does not live by bread alone
Manners maketh man
Many a little makes a mickle
Many a mickle makes a muckle
Many a true word is spoken in jest
Many hands make light work
March comes in like a lion and goes out like a lamb
Marriages are made in heaven
Marry in haste, repent at leisure
Memory is the treasure of the mind
Men get spoiled by staying, Women get spoiled by wandering
Might is right
Might makes right
Mighty oaks from little acorns grow
Milking the bull
Misery loves company
Moderation in all things
Monday's child is fair of face, Tuesday's child is full of grace, Wednesday's child is full of woe, Thursday's child has far to go, Friday's child is loving and giving, Saturday's child works hard for its living, and a child that is born on the Sabbath day is fair and wise and good and gay.
Money does not grow on trees
Money earned by deceit, goes by deceit
Money is not everything
Money makes the world go around
Money talks
Money makes many things, but also makes devil dance
More haste, less speed
Music has charms to soothe the savage beast
Nature abhors a vacuum,
Never reveal a man's wage, and woman's age
Necessity is the mother of invention
Needs must when the devil drives
Never cast a clout until May be out
Never give a sucker an even break
Never judge a book by its cover
Never let the sun go down on your anger
Never look a gift horse in the mouth
Never put off until tomorrow what you can do today
Never speak ill of the dead
Never say never
Never tell tales out of school
Nine tailors make a man,
No guts, no glory
No man can serve two masters
No man is an island
No names, no pack-drill
No news is good news
No one can make you feel inferior without your consent
No pain, no gain
No rest for the wicked
Nothing is certain but death and taxes
Nothing succeeds like success,
Nothing ventured, nothing gained
Once a witch always a witch
Oil and water do not mix
Old soldiers never die; they just fade away
Once a thief, always a thief
Once bitten, twice shy
One good turn deserves another
One half of the world does not know how the other half lives
One hand washes the other
One man's meat is another man's poison
One might as well be hanged for a sheep as a lamb
One law for the rich and another for the poor
One swallow does not make a summer
One who believes in Sword, dies by the Sword
One year's seeding makes seven years weeding
Only fools and horses work
Opportunity never knocks twice at any man's door
Out of sight, out of mind
Over greedy man, over wrathful woman will never flourish
Parsley seed goes nine times to the Devil
Patience is a virtue
Pearls of wisdom
Penny wise and pound foolish
People who live in glass houses should not throw stones
Physician, heal thyself
Possession is nine-tenths of the law
Power corrupts; absolute power corrupts absolutely
Practice makes perfect
Practice what you preach
Prevention is better than cure
Pride goes before a fall
Procrastination is the thief of time
Put your best foot forward
Put your money where your mouth is
Red sky at night shepherds delight; red sky in the morning, shepherds warning
Revenge is a dish best served cold
Revenge is sweet
Rome was not built in a day,
Right or wrong, my country
See a penny and pick it up, all the day you will have good luck; see a penny and let it lay, bad luck you will have all day
See no evil, hear no evil, speak no evil
Seeing is believing
Seek and ye shall find
Set a thief to catch a thief
Shiny are the distant hills
Shrouds have no pockets
Silence is golden
Slow and steady wins the race
Slow but sure
Softly, softly, catchee monkey
Sometimes we are the student. Sometimes we are the master. And sometimes we are merely the lesson
Spare the rod and spoil the child
Speak as you find
Speak softly and carry a big stick
Speech is silver
Sticks and stones may break my bones, but words will never hurt me
Still waters run deep
Strike while the iron is hot
Stupid is as stupid does
Success has many fathers, while failure is an orphan
Take care of the pennies, and the pounds will take care of themselves
Talk is cheap
Talk of the Devil, and he is bound to appear
Tell me who your friends are, and I'll tell you who you are
Tell the truth and shame the Devil
That which does not kill us makes us stronger
The age of miracles is past
The apple never falls far from the tree
The best defence is a good offence
The best-laid schemes of mice and men often go awry
The best things in life are free
The bigger they are, the harder they fall
The boy is father to the man
The bread never falls but on its buttered side
The child is the father of the man
The cobbler always wears the worst shoes
The course of true love never did run smooth
The customer is always right
The darkest hour is just before the dawn
The devil finds work for idle hands
The Devil looks after his own
The early bird catches the worm
The end justifies the means
The exception which proves the rule
The female of the species is more deadly than the male
The good die young
The grass is always greener on the other side of the fence
The hand that rocks the cradle rules the world
The husband is always the last to know
The innocent seldom find an uncomfortable pillow.
The labourer is worthy of his hire
The leopard does not change his spots
The longest day must have an end
The longest journey starts with a single step
The moon is made of green cheese
The more the merrier
The more things change, the more they stay the same
The only way to understand a woman is to love her
The pen is mightier than the sword
The proof of the pudding is in the eating
The road to Hell is paved with good intentions
The shoemaker's son always goes barefoot
The squeaking wheel gets the grease
The straw that broke the camel's back
The way to a man's heart is through his stomach
There ain't no such thing as a free lunch
There are more ways of killing a cat than choking it with cream
There are none so blind as those that will not see
There are two sides to every question
There but for the grace of God go I
There is an exception to every rule
There are always more fish in the sea
There is honour among thieves
There is many a good tune played on an old fiddle
There is many a slip 'twixt cup and lip
There is more than one way to skin a cat
There is no accounting for tastes
There is no fool like an old fool
There is no place like home
There is no smoke without fire
There is no such thing as a free lunch
There is no such thing as bad publicity
There is no time like the present
There is none so blind as those who will not see
There's none so deaf as those who will not hear
There is nowt so queer as folk
There is one born every minute
There is safety in numbers
They that sow the wind shall reap the whirlwind
Third time is a charm
Those who do not learn from history are doomed to repeat it
Those who live in glass houses should not throw stones
Those who sleep with dogs will rise with fleas
Time and tide wait for no man
Time flies
Time is a great healer
Time is money
Time will tell
Tis better to have loved and lost than never to have loved at all
To be worn out is to be renewed.
To each his own.
To err is human, to forgive divine
To the victor go the spoils
To travel hopefully is a better thing than to arrive
Tomorrow is another day
Tomorrow never comes
Too many cooks spoil the broth
Truth is stranger than fiction
Truth will out
Two blacks do not make a white
Two heads are better than one
Two is company, but three is a crowd
Two wrongs do not make a right
Variety is the spice of life.
Walk softly but carry a big stick.
Walnuts and pears you plant for your heirs
Waste not, want not
What cannot be cured must be endured
What goes around, comes around
What goes up must come down
What you lose on the swings you gain on the roundabouts
What is sauce for the goose is sauce for the gander
When in Rome, do as the Romans do.
When it rains it pours.
When the cat is away, the mice will play
When the going gets tough, the tough get going
When the oak is before the ash, then you will only get a splash; when the ash is before the oak, then you may expect a soak
When three women gather, it becomes noisy.
What the eye does not see, the heart does not grieve over
Where there is a will there is a way
Where there is muck there is brass
Whether you think you can, or you think you can't, you're right.
While there is life there is hope
Whom the Gods love die young
Why keep a dog and bark yourself?
With a responsibility comes great power
Woman is the root of both good and evil
Wonders will never cease
Work expands so as to fill the time available
Worrying never did anyone any good
You ain't seen nothing yet
You are never too old to learn
You are what you eat
You can have too much of a good thing
You can lead a horse to water, but you cannot make it drink
You cannot have your cake and eat it too
You cannot get blood out of a stone
You cannot make a silk purse from a sow's ear
You cannot make an omelette without breaking eggs
You cannot make bricks without straw
You cannot run with the hare and hunt with the hounds
You cannot teach an old dog new tricks
You cannot judge a book by its cover
You cannot win them all
You catch more flies with honey than with vinegar
You pay your money and you take your choice
Youth is wasted on the young
You must have rocks in your head
+2057
View File
File diff suppressed because it is too large Load Diff
-11
View File
@@ -1,11 +0,0 @@
import sys
import typing
import discord
# Let's do all the dumb version checking in one place.
if discord.version_info.major < 1:
print("You are not running the rewritten version of discord.py.\n\n"
"In order to use Red v3 you MUST be running d.py version"
" >= 1.0.0.")
sys.exit(1)
-170
View File
@@ -1,170 +0,0 @@
#!/usr/bin/env python
# Discord Version check
import sys
import discord
from redbot.core.bot import Red, ExitCodes
from redbot.core.cog_manager import CogManagerUI
from redbot.core.data_manager import load_basic_configuration, config_file
from redbot.core.json_io import JsonIO
from redbot.core.global_checks import init_global_checks
from redbot.core.events import init_events
from redbot.core.cli import interactive_config, confirm, parse_cli_flags, ask_sentry
from redbot.core.core_commands import Core
from redbot.core.dev_commands import Dev
from redbot.core import rpc, __version__
import asyncio
import logging.handlers
import logging
import os
#
# Red - Discord Bot v3
#
# Made by Twentysix, improved by many
#
def init_loggers(cli_flags):
# d.py stuff
dpy_logger = logging.getLogger("discord")
dpy_logger.setLevel(logging.WARNING)
console = logging.StreamHandler()
console.setLevel(logging.WARNING)
dpy_logger.addHandler(console)
# Red stuff
logger = logging.getLogger("red")
red_format = logging.Formatter(
'%(asctime)s %(levelname)s %(module)s %(funcName)s %(lineno)d: '
'%(message)s',
datefmt="[%d/%m/%Y %H:%M]")
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setFormatter(red_format)
if cli_flags.debug:
os.environ['PYTHONASYNCIODEBUG'] = '1'
logger.setLevel(logging.DEBUG)
else:
logger.setLevel(logging.WARNING)
from redbot.core.data_manager import core_data_path
logfile_path = core_data_path() / 'red.log'
fhandler = logging.handlers.RotatingFileHandler(
filename=str(logfile_path), encoding='utf-8', mode='a',
maxBytes=10**7, backupCount=5)
fhandler.setFormatter(red_format)
logger.addHandler(fhandler)
logger.addHandler(stdout_handler)
# Sentry stuff
sentry_logger = logging.getLogger("red.sentry")
sentry_logger.setLevel(logging.WARNING)
return logger, sentry_logger
async def _get_prefix_and_token(red, indict):
"""
Again, please blame <@269933075037814786> for this.
:param indict:
:return:
"""
indict['token'] = await red.db.token()
indict['prefix'] = await red.db.prefix()
indict['enable_sentry'] = await red.db.enable_sentry()
def list_instances():
if not config_file.exists():
print("No instances have been configured! Configure one "
"using `redbot-setup` before trying to run the bot!")
sys.exit(1)
else:
data = JsonIO(config_file)._load_json()
text = "Configured Instances:\n\n"
for instance_name in sorted(data.keys()):
text += "{}\n".format(instance_name)
print(text)
sys.exit(0)
def main():
description = "Red - Version {}".format(__version__)
cli_flags = parse_cli_flags(sys.argv[1:])
if cli_flags.list_instances:
list_instances()
elif cli_flags.version:
print(description)
sys.exit(0)
elif not cli_flags.instance_name:
print("Error: No instance name was provided!")
sys.exit(1)
load_basic_configuration(cli_flags.instance_name)
log, sentry_log = init_loggers(cli_flags)
red = Red(cli_flags, description=description, pm_help=None)
init_global_checks(red)
init_events(red, cli_flags)
red.add_cog(Core(red))
red.add_cog(CogManagerUI())
if cli_flags.dev:
red.add_cog(Dev())
loop = asyncio.get_event_loop()
tmp_data = {}
loop.run_until_complete(_get_prefix_and_token(red, tmp_data))
token = os.environ.get("RED_TOKEN", tmp_data['token'])
prefix = cli_flags.prefix or tmp_data['prefix']
if token is None or not prefix:
if cli_flags.no_prompt is False:
new_token = interactive_config(red, token_set=bool(token),
prefix_set=bool(prefix))
if new_token:
token = new_token
else:
log.critical("Token and prefix must be set in order to login.")
sys.exit(1)
loop.run_until_complete(_get_prefix_and_token(red, tmp_data))
if tmp_data['enable_sentry']:
red.enable_sentry()
cleanup_tasks = True
try:
loop.run_until_complete(red.start(token, bot=not cli_flags.not_bot))
except discord.LoginFailure:
cleanup_tasks = False # No login happened, no need for this
log.critical("This token doesn't seem to be valid. If it belongs to "
"a user account, remember that the --not-bot flag "
"must be used. For self-bot functionalities instead, "
"--self-bot")
db_token = red.db.token()
if db_token and not cli_flags.no_prompt:
print("\nDo you want to reset the token? (y/n)")
if confirm("> "):
loop.run_until_complete(red.db.token.set(""))
print("Token has been reset.")
except KeyboardInterrupt:
log.info("Keyboard interrupt detected. Quitting...")
loop.run_until_complete(red.logout())
red._shutdown_mode = ExitCodes.SHUTDOWN
except Exception as e:
log.critical("Fatal exception", exc_info=e)
sentry_log.critical("Fatal Exception", exc_info=e)
loop.run_until_complete(red.logout())
finally:
rpc.clean_up()
if cleanup_tasks:
pending = asyncio.Task.all_tasks(loop=red.loop)
gathered = asyncio.gather(
*pending, loop=red.loop, return_exceptions=True)
gathered.cancel()
sys.exit(red._shutdown_mode.value)
if __name__ == '__main__':
main()
-5
View File
@@ -1,5 +0,0 @@
from .admin import Admin
def setup(bot):
bot.add_cog(Admin())
-391
View File
@@ -1,391 +0,0 @@
from typing import Tuple
import discord
from discord.ext import commands
from redbot.core import Config, checks
import logging
from redbot.core.utils.chat_formatting import box
from .announcer import Announcer
from .converters import MemberDefaultAuthor, SelfRole
log = logging.getLogger("red.admin")
GENERIC_FORBIDDEN = (
"I attempted to do something that Discord denied me permissions for."
" Your command failed to successfully complete."
)
HIERARCHY_ISSUE = (
"I tried to add {role.name} to {member.display_name} but that role"
" is higher than my highest role in the Discord heirarchy so I was"
" unable to successfully add it. Please give me a higher role and "
"try again."
)
USER_HIERARCHY_ISSUE = (
"I tried to add {role.name} to {member.display_name} but that role"
" is higher than your highest role in the Discord heirarchy so I was"
" unable to successfully add it. Please get a higher role and "
"try again."
)
RUNNING_ANNOUNCEMENT = (
"I am already announcing something. If you would like to make a"
" different announcement please use `{prefix}announce cancel`"
" first."
)
class Admin:
def __init__(self, config=Config):
self.conf = config.get_conf(self, 8237492837454039,
force_registration=True)
self.conf.register_global(
serverlocked=False
)
self.conf.register_guild(
announce_ignore=False,
announce_channel=None, # Integer ID
selfroles=[] # List of integer ID's
)
self.__current_announcer = None
def __unload(self):
try:
self.__current_announcer.cancel()
except AttributeError:
pass
@staticmethod
async def complain(ctx: commands.Context, message: str,
**kwargs):
await ctx.send(message.format(**kwargs))
def is_announcing(self) -> bool:
"""
Is the bot currently announcing something?
:return:
"""
if self.__current_announcer is None:
return False
return self.__current_announcer.active or False
@staticmethod
def pass_heirarchy_check(ctx: commands.Context,
role: discord.Role) -> bool:
"""
Determines if the bot has a higher role than the given one.
:param ctx:
:param role: Role object.
:return:
"""
return ctx.guild.me.top_role > role
@staticmethod
def pass_user_heirarchy_check(ctx: commands.Context,
role: discord.Role) -> bool:
"""
Determines if a user is allowed to add/remove/edit the given role.
:param ctx:
:param role:
:return:
"""
return ctx.author.top_role > role
async def _addrole(self, ctx: commands.Context, member: discord.Member,
role: discord.Role):
try:
await member.add_roles(role)
except discord.Forbidden:
if not self.pass_heirarchy_check(ctx, role):
await self.complain(ctx, HIERARCHY_ISSUE, role=role,
member=member)
else:
await self.complain(ctx, GENERIC_FORBIDDEN)
else:
await ctx.send("I successfully added {role.name} to"
" {member.display_name}".format(
role=role, member=member
))
async def _removerole(self, ctx: commands.Context, member: discord.Member,
role: discord.Role):
try:
await member.remove_roles(role)
except discord.Forbidden:
if not self.pass_heirarchy_check(ctx, role):
await self.complain(ctx, HIERARCHY_ISSUE, role=role,
member=member)
else:
await self.complain(ctx, GENERIC_FORBIDDEN)
else:
await ctx.send("I successfully removed {role.name} from"
" {member.display_name}".format(
role=role, member=member
))
@commands.command()
@commands.guild_only()
@checks.admin_or_permissions(manage_roles=True)
async def addrole(self, ctx: commands.Context, rolename: discord.Role, *,
user: MemberDefaultAuthor=None):
"""
Adds a role to a user. If user is left blank it defaults to the
author of the command.
"""
if user is None:
user = ctx.author
if self.pass_user_heirarchy_check(ctx, rolename):
# noinspection PyTypeChecker
await self._addrole(ctx, user, rolename)
else:
await self.complain(ctx, USER_HIERARCHY_ISSUE, member=ctx.author)
@commands.command()
@commands.guild_only()
@checks.admin_or_permissions(manage_roles=True)
async def removerole(self, ctx: commands.Context, rolename: discord.Role, *,
user: MemberDefaultAuthor=None):
"""
Removes a role from a user. If user is left blank it defaults to the
author of the command.
"""
if user is None:
user = ctx.author
if self.pass_user_heirarchy_check(ctx, rolename):
# noinspection PyTypeChecker
await self._removerole(ctx, user, rolename)
else:
await self.complain(ctx, USER_HIERARCHY_ISSUE)
@commands.group()
@commands.guild_only()
@checks.admin_or_permissions(manage_roles=True)
async def editrole(self, ctx: commands.Context):
"""Edits roles settings"""
if ctx.invoked_subcommand is None:
await ctx.send_help()
@editrole.command(name="colour", aliases=["color", ])
async def editrole_colour(self, ctx: commands.Context, role: discord.Role,
value: discord.Colour):
"""Edits a role's colour
Use double quotes if the role contains spaces.
Colour must be in hexadecimal format.
\"http://www.w3schools.com/colors/colors_picker.asp\"
Examples:
!editrole colour \"The Transistor\" #ff0000
!editrole colour Test #ff9900"""
author = ctx.author
reason = "{}({}) changed the colour of role '{}'".format(
author.name, author.id, role.name)
if not self.pass_user_heirarchy_check(ctx, role):
await self.complain(ctx, USER_HIERARCHY_ISSUE)
return
try:
await role.edit(reason=reason, color=value)
except discord.Forbidden:
await self.complain(ctx, GENERIC_FORBIDDEN)
else:
log.info(reason)
await ctx.send("Done.")
@editrole.command(name="name")
@checks.admin_or_permissions(administrator=True)
async def edit_role_name(self, ctx: commands.Context, role: discord.Role, *, name: str):
"""Edits a role's name
Use double quotes if the role or the name contain spaces.
Examples:
!editrole name \"The Transistor\" Test"""
author = ctx.message.author
old_name = role.name
reason = "{}({}) changed the name of role '{}' to '{}'".format(
author.name, author.id, old_name, name)
if not self.pass_user_heirarchy_check(ctx, role):
await self.complain(ctx, USER_HIERARCHY_ISSUE)
return
try:
await role.edit(reason=reason, name=name)
except discord.Forbidden:
await self.complain(ctx, GENERIC_FORBIDDEN)
else:
log.info(reason)
await ctx.send("Done.")
@commands.group(invoke_without_command=True)
@checks.is_owner()
async def announce(self, ctx: commands.Context, *, message: str):
"""
Announces a message to all servers the bot is in.
"""
if not self.is_announcing():
announcer = Announcer(ctx, message, config=self.conf)
announcer.start()
self.__current_announcer = announcer
await ctx.send("The announcement has begun.")
else:
prefix = ctx.prefix
await self.complain(ctx, RUNNING_ANNOUNCEMENT,
prefix=prefix)
@announce.command(name="cancel")
@checks.is_owner()
async def announce_cancel(self, ctx):
"""
Cancels a running announce.
"""
try:
self.__current_announcer.cancel()
except AttributeError:
pass
await ctx.send("The current announcement has been cancelled.")
@announce.command(name="channel")
@commands.guild_only()
@checks.guildowner_or_permissions(administrator=True)
async def announce_channel(self, ctx, *, channel: discord.TextChannel=None):
"""
Changes the channel on which the bot makes announcements.
"""
if channel is None:
channel = ctx.channel
await self.conf.guild(ctx.guild).announce_channel.set(channel.id)
await ctx.send("The announcement channel has been set to {}".format(
channel.mention
))
@announce.command(name="ignore")
@commands.guild_only()
@checks.guildowner_or_permissions(administrator=True)
async def announce_ignore(self, ctx, *, guild: discord.Guild=None):
"""
Toggles whether the announcements will ignore the given server.
Defaults to the current server if none is provided.
"""
if guild is None:
guild = ctx.guild
ignored = await self.conf.guild(guild).announce_ignore()
await self.conf.guild(guild).announce_ignore.set(not ignored)
verb = "will" if ignored else "will not"
await ctx.send("The server {} {} receive announcements.".format(
guild.name, verb
))
async def _valid_selfroles(self, guild: discord.Guild) -> Tuple[discord.Role]:
"""
Returns a list of valid selfroles
:param guild:
:return:
"""
selfrole_ids = set(await self.conf.guild(guild).selfroles())
guild_roles = guild.roles
valid_roles = tuple(r for r in guild_roles if r.id in selfrole_ids)
valid_role_ids = set(r.id for r in valid_roles)
if selfrole_ids != valid_role_ids:
await self.conf.guild(guild).selfroles.set(valid_role_ids)
# noinspection PyTypeChecker
return valid_roles
@commands.group(invoke_without_command=True)
async def selfrole(self, ctx: commands.Context, *, selfrole: SelfRole):
"""
Add a role to yourself that server admins have configured as
user settable.
"""
# noinspection PyTypeChecker
await self._addrole(ctx, ctx.author, selfrole)
@selfrole.command(name="remove")
async def selfrole_remove(self, ctx: commands.Context, *, selfrole: SelfRole):
"""
Removes a selfrole from yourself.
"""
# noinspection PyTypeChecker
await self._removerole(ctx, ctx.author, selfrole)
@selfrole.command(name="add")
@commands.has_permissions(manage_roles=True)
async def selfrole_add(self, ctx: commands.Context, *, role: discord.Role):
"""
Add a role to the list of available selfroles.
"""
async with self.conf.guild(ctx.guild).selfroles() as curr_selfroles:
if role.id not in curr_selfroles:
curr_selfroles.append(role.id)
await ctx.send("The selfroles list has been successfully modified.")
@selfrole.command(name="delete")
@commands.has_permissions(manage_roles=True)
async def selfrole_delete(self, ctx: commands.Context, *, role: SelfRole):
"""
Removes a role from the list of available selfroles.
"""
async with self.conf.guild(ctx.guild).selfroles() as curr_selfroles:
curr_selfroles.remove(role.id)
await ctx.send("The selfroles list has been successfully modified.")
@selfrole.command(name="list")
async def selfrole_list(self, ctx: commands.Context):
"""
Lists all available selfroles.
"""
selfroles = await self._valid_selfroles(ctx.guild)
fmt_selfroles = "\n".join(["+ " + r.name for r in selfroles])
msg = "Available Selfroles:\n{}".format(fmt_selfroles)
await ctx.send(box(msg, "diff"))
async def _serverlock_check(self, guild: discord.Guild) -> bool:
"""
Checks if serverlocked is enabled.
:param guild:
:return: True if locked and left server
"""
if await self.conf.serverlocked():
await guild.leave()
return True
return False
@commands.command()
@checks.is_owner()
async def serverlock(self, ctx: commands.Context):
"""
Locks a bot to its current servers only.
"""
serverlocked = await self.conf.serverlocked()
await self.conf.serverlocked.set(not serverlocked)
verb = "is now" if not serverlocked else "is no longer"
await ctx.send("The bot {} serverlocked.".format(verb))
# region Event Handlers
async def on_guild_join(self, guild: discord.Guild):
if await self._serverlock_check(guild):
return
# endregion
-74
View File
@@ -1,74 +0,0 @@
import asyncio
import discord
from discord.ext import commands
class Announcer:
def __init__(self, ctx: commands.Context,
message: str,
config=None):
"""
:param ctx:
:param message:
:param config: Used to determine channel overrides
"""
self.ctx = ctx
self.message = message
self.config = config
self.active = None
def start(self):
"""
Starts an announcement.
:return:
"""
if self.active is None:
self.active = True
self.ctx.bot.loop.create_task(self.announcer())
def cancel(self):
"""
Cancels a running announcement.
:return:
"""
self.active = False
async def _get_announce_channel(self, guild: discord.Guild) -> discord.TextChannel:
channel_id = await self.config.guild(guild).announce_channel()
channel = None
if channel_id is not None:
channel = guild.get_channel(channel_id)
if channel is None:
channel = guild.system_channel
if channel is None:
channel = guild.text_channels[0]
return channel
async def announcer(self):
guild_list = self.ctx.bot.guilds
bot_owner = (await self.ctx.bot.application_info()).owner
for g in guild_list:
if not self.active:
return
if await self.config.guild(g).announce_ignore():
continue
channel = await self._get_announce_channel(g)
try:
await channel.send(self.message)
except discord.Forbidden:
await bot_owner.send("I could not announce to server: {}".format(
g.id
))
await asyncio.sleep(0.5)
self.active = False
-33
View File
@@ -1,33 +0,0 @@
import discord
from discord.ext import commands
class MemberDefaultAuthor(commands.Converter):
async def convert(self, ctx: commands.Context, arg: str) -> discord.Member:
member_converter = commands.MemberConverter()
try:
member = await member_converter.convert(ctx, arg)
except commands.BadArgument:
if arg.strip() != "":
raise
else:
member = ctx.author
return member
class SelfRole(commands.Converter):
async def convert(self, ctx: commands.Context, arg: str) -> discord.Role:
admin = ctx.command.instance
if admin is None:
raise commands.BadArgument("Admin is not loaded.")
conf = admin.conf
selfroles = await conf.guild(ctx.guild).selfroles()
role_converter = commands.RoleConverter()
role = await role_converter.convert(ctx, arg)
if role.id not in selfroles:
raise commands.BadArgument("The provided role is not a valid"
" selfrole.")
return role
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:41-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Arabic\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: ar\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: ar_SA\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Bulgarian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: bg\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: bg_BG\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Danish\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: da\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: da_DK\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: German\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: de\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: de_DE\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Greek\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: el\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: el_GR\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Pirate English\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: en-PT\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: en_PT\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:41-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Spanish\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: es-ES\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: es_ES\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Finnish\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: fi\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: fi_FI\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:41-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: French\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: fr\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: fr_FR\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Hungarian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: hu\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: hu_HU\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Indonesian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: id\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: id_ID\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Italian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: it\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: it_IT\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Japanese\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: ja\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: ja_JP\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Korean\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: ko\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: ko_KR\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: LOLCAT\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: lol\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: lol_US\n"
-17
View File
@@ -1,17 +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: 2018-02-18 14:42+AKST\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=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Dutch\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: nl\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: nl_NL\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Norwegian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: no\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: no_NO\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Polish\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=4; plural=((n == 1) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || n%10 == 1 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 12 && n%100 <= 14)) ? 2 : 3));\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: pl\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: pl_PL\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Portuguese, Brazilian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: pt-BR\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: pt_BR\n"
-18
View File
@@ -1,18 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: red-discordbot\n"
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
"Language-Team: Portuguese\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: crowdin.com\n"
"X-Crowdin-Project: red-discordbot\n"
"X-Crowdin-Language: pt-PT\n"
"X-Crowdin-File: /cogs/admin/locales/messages.pot\n"
"Language: pt_PT\n"

Some files were not shown because too many files have changed in this diff Show More