Et bim V6

ET y'a les cogs mon p'tit tabarnak !
This commit is contained in:
Maël 2017-06-11 14:04:03 -04:00
parent 1ee3811ef2
commit 4fd8826d22
47 changed files with 2473 additions and 762 deletions

11
.idea/cogue.iml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>

View File

@ -0,0 +1,7 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="useProjectProfile" value="false" />
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.5.3 (/usr/bin/python3.5)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/cogue.iml" filepath="$PROJECT_DIR$/.idea/cogue.iml" />
</modules>
</component>
</project>

974
.idea/workspace.xml Normal file
View File

@ -0,0 +1,974 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="51a90df4-b95c-4bec-a2ea-f63465f4cb54" name="Default" comment="" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="TRACKING_ENABLED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="DatabaseView">
<option name="SHOW_INTERMEDIATE" value="true" />
<option name="GROUP_SCHEMA" value="true" />
<option name="GROUP_CONTENTS" value="false" />
<option name="SORT_POSITIONED" value="false" />
<option name="SHOW_TABLE_DETAILS" value="true" />
<option name="SHOW_EMPTY_GROUPS" value="false" />
<option name="AUTO_SCROLL_FROM_SOURCE" value="false" />
</component>
<component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
<component name="FavoritesManager">
<favorites_list name="cogue" />
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="utility.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/cogs/utility.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2314">
<caret line="89" column="67" lean-forward="false" selection-start-line="89" selection-start-column="67" selection-end-line="89" selection-end-column="67" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="arrays.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/../old/botassets/arrays.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="78">
<caret line="3" column="7" lean-forward="false" selection-start-line="3" selection-start-column="6" selection-end-line="3" selection-end-column="7" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="basics.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/cogs/basics.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="464">
<caret line="28" column="49" lean-forward="false" selection-start-line="28" selection-start-column="49" selection-end-line="28" selection-end-column="49" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="funs.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/cogs/funs.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="468">
<caret line="18" column="27" lean-forward="true" selection-start-line="18" selection-start-column="27" selection-end-line="18" selection-end-column="48" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="search.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/cogs/search.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="988">
<caret line="38" column="58" lean-forward="false" selection-start-line="38" selection-start-column="58" selection-end-line="38" selection-end-column="58" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="ci.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/cogs/ci.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="672">
<caret line="116" column="0" lean-forward="true" selection-start-line="116" selection-start-column="0" selection-end-line="116" selection-end-column="0" />
<folding>
<element signature="e#0#32#0" expanded="true" />
<marker date="1497202848364" expanded="true" signature="272:523" ph="CREATE TABLE... IF" />
<marker date="1497202848364" expanded="true" signature="1348:1456" ph="SELECT useri... users" />
<marker date="1497202848364" expanded="true" signature="2659:2702" ph="SELECT id, u... users" />
<marker date="1497202848364" expanded="true" signature="2922:3023" ph="INSERT INTO users... " />
<marker date="1497202848364" expanded="true" signature="3625:3668" ph="SELECT id, u... users" />
<marker date="1497202848364" expanded="true" signature="3810:3854" ph="UPDATE users... " />
<marker date="1497202848364" expanded="true" signature="4510:4553" ph="SELECT id, u... users" />
<marker date="1497202848364" expanded="true" signature="4695:4735" ph="UPDATE users... " />
<marker date="1497202848364" expanded="true" signature="5301:5344" ph="SELECT id, u... users" />
<marker date="1497202848364" expanded="true" signature="5474:5516" ph="UPDATE users... " />
<marker date="1497202848364" expanded="true" signature="5939:5969" ph="SELECT id, u... users" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="admin.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/cogs/admin.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="884">
<caret line="49" column="35" lean-forward="false" selection-start-line="49" selection-start-column="35" selection-end-line="49" selection-end-column="35" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="checks.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/cogs/utils/checks.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="229">
<caret line="10" column="25" lean-forward="true" selection-start-line="10" selection-start-column="25" selection-end-line="10" selection-end-column="25" />
<folding>
<element signature="e#24#44#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="bot.py" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/bot.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="276">
<caret line="72" column="81" lean-forward="false" selection-start-line="72" selection-start-column="81" selection-end-line="72" selection-end-column="81" />
<folding />
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Python Script" />
</list>
</option>
</component>
<component name="FindInProjectRecents">
<findStrings>
<find>datetime</find>
<find>args_</find>
<find>utc =</find>
<find>os_info</find>
<find>rigole</find>
<find>bobon</find>
<find>fast</find>
<find>requests</find>
<find>joke</find>
<find>time</find>
<find>clock</find>
<find>choic</find>
<find>edit</find>
<find>ctx</find>
<find>print(</find>
<find>delete</find>
<find>message</find>
<find>ping</find>
<find>e</find>
<find>you cant</find>
<find>avatar</find>
<find>args</find>
<find>do</find>
<find>warn</find>
<find>is_owner</find>
<find>thuna</find>
<find>wi</find>
<find>str</find>
<find>269156684155453451</find>
<find>print</find>
</findStrings>
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/cogs/utils/funs.py" />
<option value="$PROJECT_DIR$/cogs/json.py" />
<option value="$PROJECT_DIR$/cogs/aaa.py" />
<option value="$PROJECT_DIR$/texts/info.md" />
<option value="$PROJECT_DIR$/texts/help.md" />
<option value="$PROJECT_DIR$/texts/jokes.json" />
<option value="$PROJECT_DIR$/texts/ytb.json" />
<option value="$PROJECT_DIR$/cogs/utility.py" />
<option value="$PROJECT_DIR$/cogs/utils/config.py" />
<option value="$PROJECT_DIR$/cogs/search.py" />
<option value="$PROJECT_DIR$/cogs/funs.py" />
<option value="$USER_HOME$/css.css" />
<option value="$PROJECT_DIR$/cogs/utils/checks.py" />
<option value="$PROJECT_DIR$/cogs/basics.py" />
<option value="$PROJECT_DIR$/cogs/admin.py" />
<option value="$PROJECT_DIR$/cogs/ci.py" />
<option value="$PROJECT_DIR$/bot.py" />
</list>
</option>
</component>
<component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsGulpfileManager">
<detection-done>true</detection-done>
<sorting>DEFINITION_ORDER</sorting>
</component>
<component name="ProjectFrameBounds">
<option name="x" value="1920" />
<option name="y" value="27" />
<option name="width" value="1900" />
<option name="height" value="793" />
</component>
<component name="ProjectView">
<navigator currentView="ProjectPane" proportions="" version="1">
<flattenPackages />
<showMembers />
<showModules />
<showLibraryContents />
<hideEmptyPackages />
<abbreviatePackageNames />
<autoscrollToSource />
<autoscrollFromSource />
<sortByType />
<manualOrder />
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="ProjectPane">
<subPane>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="cogue" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="External Libraries" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ExternalLibrariesNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="&lt; Python 3.5.3 (/usr/bin/python3.5) &gt;" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="cogue" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="cogue" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="cogue" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="cogue" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="texts" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="cogue" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="cogue" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="cogs" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
</subPane>
</pane>
<pane id="Scratches" />
<pane id="Scope" />
</panes>
</component>
<component name="PropertiesComponent">
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="settings.editor.selected.configurable" value="preferences.keymap" />
</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/cogs" />
</key>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager">
<configuration default="true" type="DjangoTestsConfigurationType" factoryName="Django tests">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="cogue" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="TARGET" value="" />
<option name="SETTINGS_FILE" value="" />
<option name="CUSTOM_SETTINGS" value="false" />
<option name="USE_OPTIONS" value="false" />
<option name="OPTIONS" value="" />
<method />
</configuration>
<configuration default="true" type="JavaScriptTestRunnerJest" factoryName="Jest">
<node-interpreter value="project" />
<working-dir value="" />
<envs />
<scope-kind value="ALL" />
<method />
</configuration>
<configuration default="true" type="JavaScriptTestRunnerProtractor" factoryName="Protractor">
<config-file value="" />
<node-interpreter value="project" />
<envs />
<method />
</configuration>
<configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
<method />
</configuration>
<configuration default="true" type="PyBehaveRunConfigurationType" factoryName="Behave">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="cogue" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="ADDITIONAL_ARGS" value="" />
<method />
</configuration>
<configuration default="true" type="PyLettuceRunConfigurationType" factoryName="Lettuce">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="cogue" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="ADDITIONAL_ARGS" value="" />
<method />
</configuration>
<configuration default="true" type="PythonConfigurationType" factoryName="Python">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="cogue" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="SCRIPT_NAME" value="" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<method />
</configuration>
<configuration default="true" type="Tox" factoryName="Tox">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<module name="cogue" />
<method />
</configuration>
<configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js">
<node-interpreter>project</node-interpreter>
<node-options />
<gulpfile />
<tasks />
<arguments />
<envs />
<method />
</configuration>
<configuration default="true" type="js.build_tools.npm" factoryName="npm">
<command value="run" />
<scripts />
<node-interpreter value="project" />
<envs />
<method />
</configuration>
<configuration default="true" type="tests" factoryName="Doctests">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="cogue" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="SCRIPT_NAME" value="" />
<option name="CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="FOLDER_NAME" value="" />
<option name="TEST_TYPE" value="TEST_SCRIPT" />
<option name="PATTERN" value="" />
<option name="USE_PATTERN" value="false" />
<method />
</configuration>
<configuration default="true" type="tests" factoryName="Unittests">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="cogue" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;.&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method />
</configuration>
</component>
<component name="ShelveChangesManager" show_recycled="false">
<option name="remove_strategy" value="false" />
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="51a90df4-b95c-4bec-a2ea-f63465f4cb54" name="Default" comment="" />
<created>1495903833631</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1495903833631</updated>
</task>
<servers />
</component>
<component name="TodoView">
<todo-panel id="selected-file">
<is-autoscroll-to-source value="true" />
</todo-panel>
<todo-panel id="all">
<are-packages-shown value="true" />
<is-autoscroll-to-source value="true" />
</todo-panel>
</component>
<component name="ToolWindowManager">
<frame x="1920" y="27" width="1900" height="793" extended-state="0" />
<editor active="true" />
<layout>
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.21069519" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3292683" sideWeight="0.50216216" order="7" side_tool="true" content_ui="tabs" />
<window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="10" side_tool="false" content_ui="tabs" />
<window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.11899564" sideWeight="0.49783784" order="8" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.24973261" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.26965067" sideWeight="0.49783784" order="9" side_tool="false" content_ui="tabs" />
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Data View" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
</layout>
<layout-to-restore>
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3292683" sideWeight="0.50216216" order="7" side_tool="true" content_ui="tabs" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="10" side_tool="false" content_ui="tabs" />
<window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.11899564" sideWeight="0.49783784" order="8" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.26965067" sideWeight="0.49783784" order="9" side_tool="false" content_ui="tabs" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.21069519" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
<window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.24973261" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Data View" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
</layout-to-restore>
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="processedProjectFiles" value="true" />
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/cogs/admin.py</url>
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/cogs/admin.py</url>
<line>42</line>
<option name="timeStamp" value="1" />
</line-breakpoint>
</breakpoints>
<option name="time" value="2" />
</breakpoint-manager>
<watches-manager />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/cogs/basics.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="26">
<caret line="8" column="0" lean-forward="false" selection-start-line="8" selection-start-column="0" selection-end-line="8" selection-end-column="0" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/texts/jokes.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="312">
<caret line="12" column="140" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="13" selection-end-column="1" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/params.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="156">
<caret line="6" column="0" lean-forward="false" selection-start-line="6" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/admin.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="234">
<caret line="16" column="19" lean-forward="false" selection-start-line="16" selection-start-column="19" selection-end-line="16" selection-end-column="19" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/texts/ytb.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="234">
<caret line="9" column="159" lean-forward="false" selection-start-line="9" selection-start-column="159" selection-end-line="9" selection-end-column="159" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/funs.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2054">
<caret line="87" column="0" lean-forward="false" selection-start-line="87" selection-start-column="0" selection-end-line="91" selection-end-column="0" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/bot.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="442">
<caret line="27" column="17" lean-forward="false" selection-start-line="27" selection-start-column="17" selection-end-line="27" selection-end-column="17" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/../old/botassets/arrays.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="78">
<caret line="3" column="8" lean-forward="false" selection-start-line="3" selection-start-column="0" selection-end-line="3" selection-end-column="8" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/basics.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="26">
<caret line="8" column="0" lean-forward="true" selection-start-line="8" selection-start-column="0" selection-end-line="8" selection-end-column="0" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/funs.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1066">
<caret line="49" column="0" lean-forward="true" selection-start-line="49" selection-start-column="0" selection-end-line="49" selection-end-column="0" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/texts/jokes.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="312">
<caret line="12" column="140" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="13" selection-end-column="1" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/params.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="156">
<caret line="6" column="0" lean-forward="false" selection-start-line="6" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/admin.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="234">
<caret line="16" column="19" lean-forward="false" selection-start-line="16" selection-start-column="19" selection-end-line="16" selection-end-column="19" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/texts/ytb.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="234">
<caret line="9" column="159" lean-forward="false" selection-start-line="9" selection-start-column="159" selection-end-line="9" selection-end-column="159" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/utility.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2964">
<caret line="122" column="0" lean-forward="true" selection-start-line="122" selection-start-column="0" selection-end-line="122" selection-end-column="0" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/bot.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1170">
<caret line="55" column="0" lean-forward="false" selection-start-line="55" selection-start-column="0" selection-end-line="56" selection-end-column="31" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/../old/main.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="12792">
<caret line="493" column="0" lean-forward="true" selection-start-line="493" selection-start-column="0" selection-end-line="497" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/basics.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="702">
<caret line="33" column="14" lean-forward="false" selection-start-line="33" selection-start-column="14" selection-end-line="33" selection-end-column="14" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/texts/jokes.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="338">
<caret line="13" column="3" lean-forward="false" selection-start-line="13" selection-start-column="3" selection-end-line="13" selection-end-column="3" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/../old/botassets/arrays.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="26">
<caret line="1" column="12" lean-forward="false" selection-start-line="1" selection-start-column="0" selection-end-line="2" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/params.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="156">
<caret line="6" column="0" lean-forward="true" selection-start-line="6" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/admin.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/funs.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1170">
<caret line="53" column="0" lean-forward="false" selection-start-line="53" selection-start-column="0" selection-end-line="53" selection-end-column="0" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/bot.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="494">
<caret line="29" column="14" lean-forward="false" selection-start-line="29" selection-start-column="14" selection-end-line="29" selection-end-column="14" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/basics.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1170">
<caret line="51" column="18" lean-forward="false" selection-start-line="51" selection-start-column="18" selection-end-line="51" selection-end-column="18" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/aaa.py" />
<entry file="file://$PROJECT_DIR$/cogs/admin.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/funs.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="364">
<caret line="20" column="27" lean-forward="false" selection-start-line="20" selection-start-column="27" selection-end-line="20" selection-end-column="27" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/bot.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/json.py" />
<entry file="file://$PROJECT_DIR$/cogs/aaa.py" />
<entry file="file://$PROJECT_DIR$/cogs/test.py" />
<entry file="file://$PROJECT_DIR$/texts/help.md">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="572">
<caret line="36" column="0" lean-forward="false" selection-start-line="36" selection-start-column="0" selection-end-line="36" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/texts/info.md">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/../old/botassets/imports.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="416">
<caret line="16" column="1" lean-forward="false" selection-start-line="16" selection-start-column="1" selection-end-line="16" selection-end-column="26" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/../old/main.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="230">
<caret line="493" column="0" lean-forward="false" selection-start-line="493" selection-start-column="0" selection-end-line="497" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/texts/pokemons.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="47">
<caret line="0" column="354" lean-forward="true" selection-start-line="0" selection-start-column="354" selection-end-line="0" selection-end-column="370" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/texts/ytb.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="234">
<caret line="9" column="159" lean-forward="false" selection-start-line="9" selection-start-column="159" selection-end-line="9" selection-end-column="159" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/params.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="156">
<caret line="6" column="0" lean-forward="false" selection-start-line="6" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/texts/jokes.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="312">
<caret line="12" column="140" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="13" selection-end-column="1" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/utils/config.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="576">
<caret line="31" column="21" lean-forward="false" selection-start-line="31" selection-start-column="21" selection-end-line="31" selection-end-column="21" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/../old/botassets/arrays.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="78">
<caret line="3" column="7" lean-forward="false" selection-start-line="3" selection-start-column="6" selection-end-line="3" selection-end-column="7" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/funs.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="468">
<caret line="18" column="27" lean-forward="true" selection-start-line="18" selection-start-column="27" selection-end-line="18" selection-end-column="48" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/css.css">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="547">
<caret line="2458" column="1" lean-forward="false" selection-start-line="2458" selection-start-column="1" selection-end-line="2458" selection-end-column="1" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/search.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="988">
<caret line="38" column="58" lean-forward="false" selection-start-line="38" selection-start-column="58" selection-end-line="38" selection-end-column="58" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/utility.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2314">
<caret line="89" column="67" lean-forward="false" selection-start-line="89" selection-start-column="67" selection-end-line="89" selection-end-column="67" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/basics.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="464">
<caret line="28" column="49" lean-forward="false" selection-start-line="28" selection-start-column="49" selection-end-line="28" selection-end-column="49" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/utils/checks.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="229">
<caret line="10" column="25" lean-forward="true" selection-start-line="10" selection-start-column="25" selection-end-line="10" selection-end-column="25" />
<folding>
<element signature="e#24#44#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/admin.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="884">
<caret line="49" column="35" lean-forward="false" selection-start-line="49" selection-start-column="35" selection-end-line="49" selection-end-column="35" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/cogs/ci.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="672">
<caret line="116" column="0" lean-forward="true" selection-start-line="116" selection-start-column="0" selection-end-line="116" selection-end-column="0" />
<folding>
<element signature="e#0#32#0" expanded="true" />
<marker date="1497202848364" expanded="true" signature="272:523" ph="CREATE TABLE... IF" />
<marker date="1497202848364" expanded="true" signature="1348:1456" ph="SELECT useri... users" />
<marker date="1497202848364" expanded="true" signature="2659:2702" ph="SELECT id, u... users" />
<marker date="1497202848364" expanded="true" signature="2922:3023" ph="INSERT INTO users... " />
<marker date="1497202848364" expanded="true" signature="3625:3668" ph="SELECT id, u... users" />
<marker date="1497202848364" expanded="true" signature="3810:3854" ph="UPDATE users... " />
<marker date="1497202848364" expanded="true" signature="4510:4553" ph="SELECT id, u... users" />
<marker date="1497202848364" expanded="true" signature="4695:4735" ph="UPDATE users... " />
<marker date="1497202848364" expanded="true" signature="5301:5344" ph="SELECT id, u... users" />
<marker date="1497202848364" expanded="true" signature="5474:5516" ph="UPDATE users... " />
<marker date="1497202848364" expanded="true" signature="5939:5969" ph="SELECT id, u... users" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/bot.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="276">
<caret line="72" column="81" lean-forward="false" selection-start-line="72" selection-start-column="81" selection-end-line="72" selection-end-column="81" />
<folding />
</state>
</provider>
</entry>
</component>
</project>

View File

@ -1,23 +0,0 @@
# TuxBot
## Description
TuxBot, un bot discord écrit en Python.
Ici se trouve le code source de ce bot proventant du serveur Discord "Aide GNU/Linux-Fr".
## Installation
- Installez Python3.5 ou plus
- Installez PIP
- Installez ``requirements.txt`` (``pip install -r requirements.txt``)
- Editez à votre guise le fichier ``config.py`` en entrant votre token
- Si vous êtes sous windows lancez le fichier ``start-windows.bat`` et si vous êtes sous linux lancer ``start.sh`` !
## Permissions :
- Gerer les messages
- Epingler les messages
- Avoir le grade ``bot-commander`` pour les commandes d'administration
## Liens utiles
- Invitation au serveur discord "Aide GNU/Linux-Fr" => http://discord.gg/B5TzW7x
- Github de la librairie ``discord.py`` => https://github.com/Rapptz/discord.py
- Site du développeur du bot => https://outout.tech

View File

@ -1,8 +0,0 @@
pokemon = ['Ratifeu','Squirtle','Ninetales','Bulbizarre','Carabaffe','Carapuce','Roucarnage','Nidorino','Akwakwak','Miaouss','Ratifeu','Squirtle','Ninetales','Bulbizarre','Carabaffe','Carapuce','Roucarnage','Nidorino','Akwakwak','Miaouss','outout14','Psyko','Arcanin','Boustiflor','Fantominus','Voltorbe','Excelangue','Poissirène','Magicarpe','Électhor','Joliflor','Cotovol','Mentali']
jokes = ['Linux : lose your time\nMac : lose your money','Un virus est un programme nocif.\nIl est petit, rapide, prend peu de place en mémoire et sais se faire discret.\nOSX n\'est donc pas un virus, c\'est un bug.','Quel est le plus gros Apple du monde ? \n *Le big MAC...*','OSX est à l\'informatique ce que la tectonick est à la musique...','Si les OS étaient des élèves:\nOSX: Le plus vieux\nLinux: Le premier de la classe\nWindows: Le différent victimisé','Windows, Mac Os et Linux sont aux toilettes. Mac OS se lave complètement les mains en sortant et déclare : Rien de plus sûr que ça ! Linux se lave uniquement deux doigts : Pas besoin de plus de sécurité ! Windows sort sans se laver les mains : Chez Windows, on ne s\'urine pas dessus !','https://cdn.discordapp.com/attachments/187284361505144833/187287424852951042/unknown.png !','Les hyperboles sa sert à manger des hyper-soupes :3 (Lawl!)','Attention : une étude récente a prouvé que la consommation prolongée de drogues peut définitivement endommager la mémoire à court terme.','https://images-1.discordapp.net/.eJwlyFEKhCAQANC7eAAn09TtNmJisTUjzkQf0d1bWHhf71Zn39WsVpHGM8Cycaa-aBbqqRZdiepeUttYZzogiaS8HgWFwcQwRme9mYbJOBet_VcwYbTB-8_wAyd-kS7UDat6XggYIuY.Tzl6-x2F39v_DjLRKkOBafZcvUg.png','C\'est un aveugle qui rentre dans un bar, qui rentre dans une chaise, qui rentre dans une table,..', 'Le comble de Windows, cest que pour larrêter, il faut cliquer sur démarrer x)', 'C\'est un type qui rentre dans un bar et qui s\'exclame "Salut c\'est moi !", tout le monde se retourne, c\'était pas lui...', 'Que prend un éléphant dans un bar ? De la place...', 'Un zoophile prend son élan avant de rentrer dans un bar :D !', 'Pourquoi un aveugle vous tutoi ? Car il ne vous voit pas.....', 'C\'est une requête SQL qui rentre dans un bar et qui s\'adresse à deux tables : Puis-je vous joindre ?','Combien de développeurs faut-il pour remplacer une ampoule grillée ? Aucun, c\'est un problème Hardware.','4h du matin un homme rentre chez lui mort bourré. Pour ne pas se faire prendre par sa femme il decide de se faire un jus de citron. Le lendemain matin sa femme lui crie dessus. "Tu as encore bus comme un trou hier" L\'homme: "Mais non" La femme: "A ouais et le cannari dans le presse citron il s\'est suicider"', 'Il ne faut jamais croire les girafes, c\'est un cou monté.', 'Quelle est la seule fonctionnalité qui n\'as jamais planté sur Windows ? Le BSOD', 'Windows n\'aime pas quel l\'on appel un dossier con, car c\'est le synonyme de son créateur (Gaston Portail)', 'Pourquoi personne n\'aime ISS? Car il était utilisé par les NAZIS', 'Sous Mac il n\'y a qu\'un virus : MacOSX', 'Le meilleur entreprise de système d\'exploitation ? Apple : Ils exploitent ton argent', 'Windows est un OS. Il est dur, n\'as pas de goût et on veut l\'enterrer', '```Apple --> perdre son argent a force de tout acheter \n Android --> perdre ses données a force de se faire pirater```', 'Plusieurs scientifiques sont entrain de se demander quel est le pire : "Utiliser Windows 8" ou "Ecouter du Jul"']
youtube = ['KickSama, dessins annimés : https://www.youtube.com/user/TheKickGuy', 'U=RI, videos sur l\'électricité | Lien : https://www.youtube.com/channel/UCVqx3vXNghSqUcVg2nmegYA', 'Outout, chaine vraiment nul et peu alimenté du créateur du bot | Lien : https://www.youtube.com/channel/UC2XpYyT5X5tq9UQpXdc1JaQ', 'SuperJDay64, LP sur des jeux de type mario | Lien : https://www.youtube.com/channel/UCjkQgODdmhR9I2TatJZtGSQ/about', 'Monsieur Plouf, critiques de jeux AAA | Lien : https://www.youtube.com/channel/UCrt_PUTF9LdJyuDfXweHwuQ', 'MaxEstLa, vidéos réaction sur d\'autres chaines (c\'est presque du clash ) | Lien : https://www.youtube.com/channel/UCsk9XguwTfgbenCZ4AlIcYQ', 'BastienLePirate, astuces youtube, vidéos sur des ytubers, ...| Lien : https://www.youtube.com/channel/UCJFGk2A34R-99RIVDK2Hlwg', 'Blender Foundation, animations libre de droits réalisé en utilisant blender | Lien : https://www.youtube.com/channel/UCSMOQeBJ2RAnuFungnQOxLg', 'Met-Hardware, chaine youtube sur l\'hardware et des let\'s play ! Lien : https://www.youtube.com/channel/UC7rse81OttysA1m1yn_f-OA', 'Les teachers du net, tutoriels | Lien : https://www.youtube.com/user/hounwanou1993','5secondfilms (Anglais), des courts-métrage | Lien : https://www.youtube.com/user/5secondfilms','TomSka (Anglais), des courts-métrages | Lien : https://www.youtube.com/user/TomSka','Trash, des Tops | Lien : https://www.youtube.com/channel/UCfGfdZuYifBYb1fmZcL1JBQ','ElectronikHeart, l\'informatique sous un angle différent | Lien : https://www.youtube.com/user/ElectronikHeart','Blender Foundation, des court-métrages réalisés avec Blender | Lien : https://www.youtube.com/channel/UCSMOQeBJ2RAnuFungnQOxLg','Caljbeut, politique, etc... en dessins | Lien : https://www.youtube.com/channel/UCNM-UkIP1BL5jv9ZrN5JMCA','SetSolution, des concepts d\'Iphones, etc... | Lien : https://www.youtube.com/channel/UCAXlQL_BcggjH6MpMSekjYg']
policier = [" Humm... Overdose de GNU/Linux, suivez moi...", " Ca fonctionne comment un ethylotest, vous savez vous ?", " Wow, vous êtes trop bourré, z'avez cassé mon ethylotest!", " Heeu, vous êtes à vélo mais vous êtes bourré, c'est légal ?", " Vous n'avez pas consomé d'alchool mais vous avez consomé du Canabis, c'est pas ma mission, circulez !"]
admin_cmd = ["say", "clear", "changegame", "sendlogs"]
array_emoji = ["1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣", "🔟"]
wlcm_msgs = ['Bienvenue à toi, {0.mention} sur le mangifique discord {0.server.name} !', 'Souhaitons la bienvenue à notre nouveau membre, {0.mention} sur notre super serveur !', 'Welcome :heart:, {0.mention} sur le discord {0.server.name} !']
adios_msgs = ['Pourquoi {0.name} nous à t-il quitté ?!? Il faudra qu\'il m\'explique !', '{0.name} nous a malheuresement quitté**, il a fait une grave erreur, nous le traquerons puis nous lui feront avaler le CD de Ubuntu !!! :smirk:', '{0.name} est mort, enfin il à quitté notre discord...', ':sob: Ouiiin... {0.name} est partit de notre beau serveur !', '{0.name} nous à quitté, on ne l\'oublieras jamais... Enfaite c\'était qui encore {0.name} ?']

140
bot.py Normal file
View File

@ -0,0 +1,140 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = "Maël / Outout"
__licence__ = "WTFPL Licence 2.0"
from discord.ext import commands
import discord
from cogs.utils import checks
import datetime, re
import json, asyncio
import copy
import logging
from logging.handlers import RotatingFileHandler
import traceback
import sys
from collections import Counter
description = """
Je suis TuxBot, le bot qui vit de l'OpenSource ! ;)
"""
l_extensions = [
'cogs.basics',
'cogs.admin',
'cogs.funs',
'cogs.utility',
'cogs.search',
'cogs.ci'
]
# DISCORD LOGGER #
discord_logger = logging.getLogger('discord')
discord_logger.setLevel(logging.CRITICAL)
log = logging.getLogger()
log.setLevel(logging.INFO)
handler = logging.FileHandler(filename='logs/discord.log', encoding='utf-8', mode='w')
log.addHandler(handler)
help_attrs = dict(hidden=True, in_help=True, name="DONOTUSE")
# CREDENTIALS #
try:
def load_credentials():
with open('params.json') as f:
return json.load(f)
except:
print("Le fichier de paramètre est introuvable, veuillez le créer et le configurer.")
prefix = ['.']
bot = commands.Bot(command_prefix=prefix, description=description, pm_help=None, help_attrs=help_attrs)
@bot.event
async def on_command_error(error, ctx):
if isinstance(error, commands.NoPrivateMessage):
await bot.send_message(ctx.message.author, 'This command cannot be used in private messages.')
elif isinstance(error, commands.DisabledCommand):
await bot.send_message(ctx.message.author, 'Sorry. This command is disabled and cannot be used.')
elif isinstance(error, commands.CommandInvokeError):
print('In {0.command.qualified_name}:'.format(ctx), file=sys.stderr)
traceback.print_tb(error.original.__traceback__)
print('{0.__class__.__name__}: {0}'.format(error.original), file=sys.stderr)
@bot.event
async def on_ready():
print('---------------------')
print('Logged in as :')
print('Username: ' + bot.user.name)
print('ID: ' + bot.user.id)
print('---------------------')
await bot.change_presence(game=discord.Game(name="Manger des pommes ! .help !"), status=discord.Status("dnd"), afk=False)
if not hasattr(bot, 'uptime'):
bot.uptime = datetime.datetime.utcnow()
@bot.event
async def on_resumed():
print('resumed...')
@bot.event
async def on_message(message):
if message.author.bot:
return
if re.search(r'^(cc |bonjour |salut |hello |bjr |slt |s\'lut)?([^ ]+ ){0,3}(qui s\'y conna(î|i)(t|s)|des gens|quelqu\'un|qqun|des personnes|du monde s\'y connait)[^\?]+\?$',message.content):
await bot.send_message(message.channel, ":question: N'hésite pas à poser ta question directement {}, il n'est pas utile de demander si quelqu'un connait quelque chose avant ! :wink:".format(message.author.mention))
if re.match(r'^<@(\w+)>$', message.content):
await bot.send_message(message.channel, message.author.mention + " > Tu voulais lui dire quoi ? Tu le mentionne sans message !")
if re.match(r"[A-Z]", message.content) and not message.author.bot and len(message.content) > 5:
await bot.send_message(message.channel, message.author.mention + " > Evite les messages en majuscule, ce n'est pas la peine de crier !")
await bot.process_commands(message)
@bot.command(pass_context=True, hidden=True)
@checks.is_owner()
async def do(ctx, times : int, *, command):
"""Repeats a command a specified number of times."""
msg = copy.copy(ctx.message)
msg.content = command
for i in range(times):
await bot.process_commands(msg)
## GITHUB CMD ##
@bot.command()
async def github():
"""Pour voir mon code"""
text = "How tu veux voir mon repos Github pour me disséquer ? Pas de soucis ! Je suis un Bot, je ne ressens pas la douleur !\n https://github.com/outout14/tuxbot-bot"
em = discord.Embed(title='Repos TuxBot-Bot', description=text, colour=0xE9D460)
em.set_author(name='Outout', icon_url="https://avatars0.githubusercontent.com/u/14958554?v=3&s=400")
await bot.say(embed=em)
## LOAD ##
if __name__ == '__main__':
try:
credentials = load_credentials()
token = credentials['token']
bot.client_id = credentials['client_id']
except:
print("Impossible de démarer tuxbot.")
for extension in l_extensions:
try:
bot.load_extension(extension)
except Exception as e:
print('Impossible de charger l\'extension {}\n{}: {}'.format(extension, type(e).__name__, e))
try:
bot.run(token)
except:
print("Une erreur est survenue avec votre Token, merci de le vérifier.")
handlers = log.handlers[:]
for hdlr in handlers:
hdlr.close()
log.removeHandler(hdlr)

View File

@ -1 +0,0 @@
__all__ = ["imports","arrays"]

View File

@ -1,7 +0,0 @@
pokemon = ['Ratifeu','Squirtle','Ninetales','Bulbizarre','Carabaffe','Carapuce','Roucarnage','Nidorino','Akwakwak','Miaouss','Ratifeu','Squirtle','Ninetales','Bulbizarre','Carabaffe','Carapuce','Roucarnage','Nidorino','Akwakwak','Miaouss','outout14','Psyko','Arcanin','Boustiflor','Fantominus','Voltorbe','Excelangue','Poissirène','Magicarpe','Électhor','Joliflor','Cotovol','Mentali']
jokes = ['Linux : lose your time\nMac : lose your money','Un virus est un programme nocif.\nIl est petit, rapide, prend peu de place en mémoire et sais se faire discret.\nOSX n\'est donc pas un virus, c\'est un bug.','Quel est le plus gros Apple du monde ? \n *Le big MAC...*','OSX est à l\'informatique ce que la tectonick est à la musique...','Si les OS étaient des élèves:\nOSX: Le plus vieux\nLinux: Le premier de la classe\nWindows: Le différent victimisé','Windows, Mac Os et Linux sont aux toilettes. Mac OS se lave complètement les mains en sortant et déclare : Rien de plus sûr que ça ! Linux se lave uniquement deux doigts : Pas besoin de plus de sécurité ! Windows sort sans se laver les mains : Chez Windows, on ne s\'urine pas dessus !','https://cdn.discordapp.com/attachments/187284361505144833/187287424852951042/unknown.png !','Les hyperboles sa sert à manger des hyper-soupes :3 (Lawl!)','Attention : une étude récente a prouvé que la consommation prolongée de drogues peut définitivement endommager la mémoire à court terme.','https://images-1.discordapp.net/.eJwlyFEKhCAQANC7eAAn09TtNmJisTUjzkQf0d1bWHhf71Zn39WsVpHGM8Cycaa-aBbqqRZdiepeUttYZzogiaS8HgWFwcQwRme9mYbJOBet_VcwYbTB-8_wAyd-kS7UDat6XggYIuY.Tzl6-x2F39v_DjLRKkOBafZcvUg.png','C\'est un aveugle qui rentre dans un bar, qui rentre dans une chaise, qui rentre dans une table,..', 'Le comble de Windows, cest que pour larrêter, il faut cliquer sur démarrer x)', 'C\'est un type qui rentre dans un bar et qui s\'exclame "Salut c\'est moi !", tout le monde se retourne, c\'était pas lui...', 'Que prend un éléphant dans un bar ? De la place...', 'Un zoophile prend son élan avant de rentrer dans un bar :D !', 'Pourquoi un aveugle vous tutoi ? Car il ne vous voit pas.....', 'C\'est une requête SQL qui rentre dans un bar et qui s\'adresse à deux tables : Puis-je vous joindre ?','Combien de développeurs faut-il pour remplacer une ampoule grillée ? Aucun, c\'est un problème Hardware.','4h du matin un homme rentre chez lui mort bourré. Pour ne pas se faire prendre par sa femme il decide de se faire un jus de citron. Le lendemain matin sa femme lui crie dessus. "Tu as encore bus comme un trou hier" L\'homme: "Mais non" La femme: "A ouais et le cannari dans le presse citron il s\'est suicider"', 'Il ne faut jamais croire les girafes, c\'est un cou monté.', 'Quelle est la seule fonctionnalité qui n\'as jamais planté sur Windows ? Le BSOD', 'Windows n\'aime pas quel l\'on appel un dossier con, car c\'est le synonyme de son créateur (Gaston Portail)', 'Pourquoi personne n\'aime ISS? Car il était utilisé par les NAZIS', 'Sous Mac il n\'y a qu\'un virus : MacOSX', 'Le meilleur entreprise de système d\'exploitation ? Apple : Ils exploitent ton argent', 'Windows est un OS. Il est dur, n\'as pas de goût et on veut l\'enterrer', '```Apple --> perdre son argent a force de tout acheter \n Android --> perdre ses données a force de se faire pirater```', 'Plusieurs scientifiques sont entrain de se demander quel est le pire : "Utiliser Windows 8" ou "Ecouter du Jul"']
youtube = ['KickSama, dessins annimés : https://www.youtube.com/user/TheKickGuy', 'U=RI, videos sur l\'électricité | Lien : https://www.youtube.com/channel/UCVqx3vXNghSqUcVg2nmegYA', 'Outout, chaine vraiment nul et peu alimenté du créateur du bot | Lien : https://www.youtube.com/channel/UC2XpYyT5X5tq9UQpXdc1JaQ', 'SuperJDay64, LP sur des jeux de type mario | Lien : https://www.youtube.com/channel/UCjkQgODdmhR9I2TatJZtGSQ/about', 'Monsieur Plouf, critiques de jeux AAA | Lien : https://www.youtube.com/channel/UCrt_PUTF9LdJyuDfXweHwuQ', 'MaxEstLa, vidéos réaction sur d\'autres chaines (c\'est presque du clash ) | Lien : https://www.youtube.com/channel/UCsk9XguwTfgbenCZ4AlIcYQ', 'BastienLePirate, astuces youtube, vidéos sur des ytubers, ...| Lien : https://www.youtube.com/channel/UCJFGk2A34R-99RIVDK2Hlwg', 'Blender Foundation, animations libre de droits réalisé en utilisant blender | Lien : https://www.youtube.com/channel/UCSMOQeBJ2RAnuFungnQOxLg', 'Met-Hardware, chaine youtube sur l\'hardware et des let\'s play ! Lien : https://www.youtube.com/channel/UC7rse81OttysA1m1yn_f-OA', 'Les teachers du net, tutoriels | Lien : https://www.youtube.com/user/hounwanou1993','5secondfilms (Anglais), des courts-métrage | Lien : https://www.youtube.com/user/5secondfilms','TomSka (Anglais), des courts-métrages | Lien : https://www.youtube.com/user/TomSka','Trash, des Tops | Lien : https://www.youtube.com/channel/UCfGfdZuYifBYb1fmZcL1JBQ','ElectronikHeart, l\'informatique sous un angle différent | Lien : https://www.youtube.com/user/ElectronikHeart','Blender Foundation, des court-métrages réalisés avec Blender | Lien : https://www.youtube.com/channel/UCSMOQeBJ2RAnuFungnQOxLg','Caljbeut, politique, etc... en dessins | Lien : https://www.youtube.com/channel/UCNM-UkIP1BL5jv9ZrN5JMCA','SetSolution, des concepts d\'Iphones, etc... | Lien : https://www.youtube.com/channel/UCAXlQL_BcggjH6MpMSekjYg']
policier = [" Humm... Overdose de GNU/Linux, suivez moi...", " Ca fonctionne comment un ethylotest, vous savez vous ?", " Wow, vous êtes trop bourré, z'avez cassé mon ethylotest!", " Heeu, vous êtes à vélo mais vous êtes bourré, c'est légal ?", " Vous n'avez pas consomé d'alchool mais vous avez consomé du Canabis, c'est pas ma mission, circulez !"]
array_emoji = ["1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣", "🔟"]
wlcm_msgs = ['Bienvenue à toi, {0.mention} sur le mangifique discord {0.server.name} !', 'Souhaitons la bienvenue à notre nouveau membre, {0.mention} sur notre super serveur !', 'Welcome :heart:, {0.mention} sur le discord {0.server.name} !']
adios_msgs = ['Pourquoi {0.name} nous à t-il quitté ?!? Il faudra qu\'il m\'explique !', '{0.name} nous a malheuresement quitté, il a fait une grave erreur, nous le traquerons puis nous lui feront avaler le CD de Ubuntu !!! :smirk:', '{0.name} est mort, enfin il à quitté notre discord...', ':sob: Ouiiin... {0.name} est partit de notre beau serveur !', '{0.name} nous à quitté, on ne l\'oublieras jamais... Enfaite c\'était qui encore {0.name} ?']

View File

@ -1,21 +0,0 @@
#################
# IMPORTS #
#################
import discord ##Discord.py library
import asyncio
from config import *
import random
import time
import sys
import math
import os
import urllib
from bs4 import *
import urllib.request ##URL functions
import re
import logging
import datetime ##For Time
import pytz ##For time
import requests
import wikipedia
import sqlite3

70
cogs/admin.py Normal file
View File

@ -0,0 +1,70 @@
from discord.ext import commands
from random import choice, shuffle
import aiohttp
import asyncio
import time
import discord
import platform
from .utils import checks
class Admin:
"""Commandes secrètes d'administration."""
def __init__(self, bot):
self.bot = bot
@checks.is_owner()
@commands.command()
async def unload(self, module: str):
"""Unloads a module."""
try:
self.bot.unload_extension(module)
except Exception as e:
await self.bot.say('\N{PISTOL}')
await self.bot.say('{}: {}'.format(type(e).__name__, e))
else:
await self.bot.say('\N{OK HAND SIGN}')
@checks.is_owner()
@commands.command(name='reload_cog', hidden=True)
async def _reload(self, *, module: str):
"""Reloads a module."""
try:
self.bot.unload_extension(module)
self.bot.load_extension(module)
await self.bot.say("Nice !")
except Exception as e:
await self.bot.say(':( Erreur :')
await self.bot.say('{}: {}'.format(type(e).__name__, e))
else:
await self.bot.say('\N{OK HAND SIGN}')
@checks.is_owner()
@commands.command(name='clear', pass_context=True, hidden=True)
async def _clear(self, ctx, number: int):
try:
number = number + 1
await self.bot.purge_from(ctx.message.channel, limit=number)
await self.bot.say("Hello World !")
except Exception as e:
await self.bot.say(':sob: Une erreur est survenue : \n {}: {}'.format(type(e).__name__, e))
@checks.is_owner()
@commands.command(name='say', pass_context=True, hidden=True)
async def _say(self, ctx, dire):
try:
arg = ctx.message.content.split("say ")
await self.bot.say(arg[1])
await self.bot.delete_message(ctx.message)
except Exception as e:
await self.bot.say(':sob: Une erreur est survenue : \n {}: {}'.format(type(e).__name__, e))
@checks.is_owner()
@commands.command(pass_context=True, hidden=True)
async def _clearterm(self):
clear = "\n" * 100
print(clear)
await self.bot.say(":ok_hand: It's good")
def setup(bot):
bot.add_cog(Admin(bot))

42
cogs/basics.py Normal file
View File

@ -0,0 +1,42 @@
from discord.ext import commands
from random import choice, shuffle
import aiohttp
import asyncio
import time
import discord
import platform, socket
import os
class General:
"""Commandes générales."""
def __init__(self, bot):
self.bot = bot
##PING##
@commands.command()
async def ping(self):
"""Ping le bot"""
await self.bot.say(":ping_pong: Pong !")
##INFO##
@commands.command()
async def info(self):
"""Affiches des informations sur le bot"""
text = open('texts/info.md').read()
os_info = str(platform.system()) + " / " + str(platform.release())
em = discord.Embed(title='Informations sur TuxBot', description=text.format(os_info, platform.python_version(), socket.gethostname(), discord.__version__), colour=0x89C4F9)
em.set_footer(text=os.getcwd() + "/bot.py")
await self.bot.say(embed=em)
## HELP PLZ ##
@commands.command()
async def help(self):
"""Affiches l'aide du bot"""
text = open('texts/help.md').read()
em = discord.Embed(title='Commandes de TuxBot', description=text, colour=0x89C4F9)
await self.bot.say(embed=em)
def setup(bot):
bot.add_cog(General(bot))

144
cogs/ci.py Normal file
View File

@ -0,0 +1,144 @@
from discord.ext import commands
from random import choice, shuffle
import aiohttp
import asyncio
import discord
import platform, socket
import os
import sqlite3
#### SQL #####
conn = sqlite3.connect('tuxbot.db') #Connexion SQL
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS users(
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
userid TEXT,
username TEXT,
os TEXT,
config TEXT,
useravatar TEXT,
userbirth TEXT,
pays TEXT,
cidate TEXT,
cibureau TEXT
)
""")# Creation table Utilisateur si premiere fois
conn.commit()
class Identity:
"""Commandes des cartes d'identité ."""
def __init__(self, bot):
self.bot = bot
@commands.group(name="ci", no_pm=True, pass_context=True)
async def _ci(self, ctx):
"""Cartes d'identité"""
if ctx.invoked_subcommand is None:
text = open('texts/ci-info.md').read()
em = discord.Embed(title='Commandes de carte d\'identité de TuxBot', description=text, colour=0x89C4F9)
await self.bot.say(embed=em)
@_ci.command(pass_context=True, name="show")
async def ci_test(self, ctx, args : discord.Member):
def isexist(var):
if not var:
return "Non renseigné."
else:
return var
cursor.execute("""SELECT userid, username, useravatar, userbirth, cidate, cibureau, os, config, pays FROM users WHERE userid=?""",(args.id,))
result = cursor.fetchone()
if not result:
await self.bot.say(ctx.message.author.mention + "> :x: Désolé mais {} est sans papier !".format(args.mention))
else:
userbirth = result[3].split(" ")
cidate = result[4].split(" ")
embed=discord.Embed(title="Carte d'identité | Communisme Linuxien")
embed.set_author(name=result[1], icon_url=result[2])
embed.set_thumbnail(url = result[2])
embed.add_field(name="Nom :", value=result[1], inline=True)
embed.add_field(name="Système d'exploitation :", value=isexist(result[6]), inline=True)
embed.add_field(name="Configuration Système : ", value=isexist(result[7]), inline=True)
embed.add_field(name="Date de naissance : ", value=userbirth[0], inline=True)
embed.add_field(name="Pays : ", value=isexist(result[8]), inline=True)
embed.set_footer(text="Enregistré dans le bureau {} le {}.".format(result[5], cidate[0]))
await self.bot.say(embed=embed)
@_ci.command(pass_context=True, name="register")
async def ci_register(self, ctx):
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
existansw = cursor.fetchone()
if existansw != None:
await self.bot.say("Mais tu as déja une carte d'identité ! u_u")
else:
cursor.execute("""INSERT INTO users(userid, username, useravatar, userbirth, cidate, cibureau) VALUES(?, ?, ?, ?, ?, ?)""", (ctx.message.author.id, ctx.message.author.name, ctx.message.author.avatar_url, ctx.message.author.created_at, ctx.message.timestamp, ctx.message.server.name))
conn.commit()
await self.bot.say(":clap: Bievenue à toi {} dans le communisme {} ! Fait ``.ci`` pour plus d'informations !".format(ctx.message.author.name, ctx.message.server.name))
@_ci.command(pass_context=True, name="setconfig")
async def ci_setconfig(self, ctx, args_):
try:
args = ctx.message.content.split("setconfig ")
args = args[1]
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
existansw = cursor.fetchone()
if existansw != None:
cursor.execute("""UPDATE users SET config = ? WHERE userid = ?""", (args, ctx.message.author.id))
conn.commit()
await self.bot.say(ctx.message.author.mention + "> :ok_hand: Carte d'identité mise à jour !")
else:
await self.bot.say(ctx.message.author.mention + "> :x: Veuillez enregistrer votre carte d'identité pour commencer !")
except:
await self.bot.say(ctx.message.author.mention + "> :x: Il manque un paramètre !")
@_ci.command(pass_context=True, name="setos")
async def ci_setos(self, ctx, args_):
try:
args = ctx.message.content.split("setos ")
args = args[1]
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
existansw = cursor.fetchone()
if existansw != None:
cursor.execute("""UPDATE users SET os = ? WHERE userid = ?""", (args, ctx.message.author.id))
conn.commit()
await self.bot.say(ctx.message.author.mention + "> :ok_hand: Carte d'identité mise à jour !")
else:
await self.bot.say(ctx.message.author.mention + "> :x: Veuillez enregistrer votre carte d'identité pour commencer !")
except:
await self.bot.say(ctx.message.author.mention + "> :x: Il manque un paramètre !")
@_ci.command(pass_context=True, name="setcountry")
async def ci_setcountry(self, ctx, args):
cursor.execute("""SELECT id, userid FROM users WHERE userid=?""", (ctx.message.author.id,))
existansw = cursor.fetchone()
if existansw != None:
cursor.execute("""UPDATE users SET pays = ? WHERE userid = ?""", (args, ctx.message.author.id))
conn.commit()
await self.bot.say(ctx.message.author.mention + "> :ok_hand: Carte d'identité mise à jour !")
else:
await self.bot.say(ctx.message.author.mention + "> :x: Veuillez enregistrer votre carte d'identité pour commencer !")
@_ci.command(pass_context=True, name="list")
async def ci_list(self, ctx):
cursor.execute("""SELECT id, username FROM users""")
rows = cursor.fetchall()
msg = ""
try:
for row in rows:
msg = msg + '{0} : {1} \n'.format(row[0], row[1])
await self.bot.say(msg)
except:
await self.bot.say(":x: Pas d'entrés")
def setup(bot):
bot.add_cog(Identity(bot))

124
cogs/funs.py Normal file
View File

@ -0,0 +1,124 @@
from discord.ext import commands
from random import choice, shuffle
import aiohttp
import asyncio
import discord
import urllib.request, json
import random
import requests
class Funs:
"""Commandes funs."""
def __init__(self, bot):
self.bot = bot
@commands.command()
async def avatar(self, user : discord.Member):
"""Récuperer l'avatar de ..."""
embed = discord.Embed(title="Avatar de : " + user.name, url=user.avatar_url, description="[Voir en plus grand]({})".format(user.avatar_url))
embed.set_thumbnail(url=user.avatar_url)
await self.bot.say(embed=embed)
@commands.command()
async def btcprice(self):
"""Le prix du BTC"""
loading = await self.bot.say("_réfléchis..._")
try:
with urllib.request.urlopen("http://api.coindesk.com/v1/bpi/currentprice/EUR.json") as url:
data = json.loads(url.read().decode())
btc = data['bpi']['EUR']['rate']
btc = btc.split(".")
except:
btc = 1
if btc == 1:
await self.bot.say("Impossible d'accèder à l'API coindesk.com, veuillez réessayer ultérieurment !")
else:
await self.bot.edit_message(loading, "Un bitcoin est égal à : " + btc[0] + "")
@commands.command()
async def joke(self):
"""Print a random joke in a json file"""
with open('texts/jokes.json') as js:
jk = json.load(js)
clef = str(random.randint(1,12))
joke = jk["{}".format(clef)]
embed = discord.Embed(title="Blague _{}_ : ".format(clef), description=joke['content'], colour=0x03C9A9)
embed.set_footer(text="Par " + joke['author'])
embed.set_thumbnail(url='https://outout.tech/tuxbot/blobjoy.png')
await self.bot.say(embed=embed)
@commands.command()
async def ethylotest(self):
"""Ethylotest simulator 2018"""
results_poulet = ["Désolé mais mon ethylotest est sous Windows Vista, merci de patienter...", "_(ethylotest)_ ``Une erreur est survenue. Windows cherche une solution à se prolbème...``", "Mais j'l'ai foutu où ce p*** d'ethylotest de m..... bordel fait ch..... tab....", "C'est pas possible z'avez cassé l'ethylotest !"]
results_client = ["D'accord, il n'y a pas de problème à cela je suis complètement clean", "Bien sur si c'est votre devoir !", "Suce bi** !", "J'ai l'air d'être bourré ?", "_laissez moi prendre un bonbon à la menthe..._"]
result_p = random.choice(results_poulet)
result_c = random.choice(results_client)
await self.bot.say(":oncoming_police_car: Bonjour bonjour, controle d'alcoolémie !")
await asyncio.sleep(0.5)
await self.bot.say(":man: " + result_c)
await asyncio.sleep(1)
await self.bot.say(":police_car: " + result_p)
@commands.command()
async def coin(self):
"""Coin flip simulator 2025"""
starts_msg = ["Je lance la pièce !", "C'est partit !", "C'est une pièce de d'un cent faut pas la perdre", "C'est une pièce de d'un euro faut pas la perdre", "Je lance !"]
results_coin = ["{0} pile", "{0} face", "{1} Heu c'est quoi pile c'est quoi face enfaite ?", "{1} How shit, je crois que je l'ai perdu", "{1} Et bim je te vol ta pièce !", "{0} Oh une erreur d'impression y'a ni pile ni face !"]
start = random.choice(starts_msg)
result = random.choice(results_coin)
await self.bot.say(start)
await asyncio.sleep(0.6)
await self.bot.say(result.format(":moneybag: Et la pièce retombe sur ...", ":robot:"))
@commands.command()
async def pokemon(self):
"""Random pokemon fight"""
with open('texts/pokemons.json') as js:
jk = json.load(js)
poke1 = jk[random.randint(1, 150)]
poke2 = jk[random.randint(1, 150)]
if poke1['MaxHP'] > poke2['MaxHP']:
winer = poke1
else:
winer = poke2
await self.bot.say(":flag_white: **Le combat commence !**")
await asyncio.sleep(1)
await self.bot.say(":loudspeaker: Les concurants sont {} contre {} ! Bonne chance à eux !".format(poke1["Name"], poke2["Name"]))
await asyncio.sleep(0.5)
await self.bot.say(":boom: {} commence et utilise {}".format(poke1["Name"], poke1["Fast Attack(s)"][0]["Name"]))
await asyncio.sleep(1)
await self.bot.say(":dash: {} réplique avec {}".format(poke2["Name"], poke2["Fast Attack(s)"][0]["Name"]))
await asyncio.sleep(1.2)
await self.bot.say("_le combat continue de se dérouler..._")
await asyncio.sleep(1.5)
await self.bot.say(":trophy: Le gagnant est **{}** !".format(winer["Name"]))
@commands.command()
async def randomcat(self):
"""Display a random cat"""
r = requests.get('http://random.cat/meow.php')
cat = str(r.json()['file'])
embed = discord.Embed(title="Meow", description="[Voir le chat plus grand]({})".format(cat), colour=0x03C9A9)
embed.set_thumbnail(url=cat)
embed.set_author(name="Random.cat", url='https://random.cat/', icon_url='http://outout.tech/tuxbot/nyancat2.gif')
await self.bot.say(embed=embed)
def setup(bot):
bot.add_cog(Funs(bot))

122
cogs/search.py Normal file
View File

@ -0,0 +1,122 @@
from discord.ext import commands
import aiohttp
import asyncio
import discord
import urllib.request, json
import wikipedia, bs4
wikipedia.set_lang("fr")
class Search:
"""Commandes de WWW."""
def __init__(self, bot):
self.bot = bot
@commands.group(name="search", no_pm=True, pass_context=True)
async def _search(self, ctx):
"""Rechercher sur le world wide web"""
if ctx.invoked_subcommand is None:
text = open('texts/search.md').read()
em = discord.Embed(title='Commandes de search TuxBot', description=text, colour=0x89C4F9)
await self.bot.say(embed=em)
@_search.command(pass_context=True, name="docubuntu")
async def search_docubuntu(self, ctx, args):
await self.bot.send_typing(ctx.message.channel)
attends = await self.bot.say("_Je te cherche ça {} !_".format(ctx.message.author.mention))
html = urllib.request.urlopen("https://doc.ubuntu-fr.org/" + args).read()
if "avez suivi un lien" in str(html):
await self.bot.edit_message(attends, ":sob: Nooooon ! Cette page n'existe pas, mais tu peux toujours la créer : https://doc.ubuntu-fr.org/"+ args)
else:
await self.bot.delete_message(attends)
embed = discord.Embed(description="Voila j'ai trouvé ! Voici la page ramenant à votre recherche, toujours aussi bien rédigée :wink: : https://doc.ubuntu-fr.org/" + args, url='http://doc.ubuntu-fr.org/')
embed.set_author(name="DocUbuntu-Fr", url='http://doc.ubuntu-fr.org/', icon_url='http://outout.tech/tuxbot/ubuntu.png')
embed.set_thumbnail(url='http://outout.tech/tuxbot/ubuntu.png')
embed.set_footer(text="Merci à ceux qui ont pris le temps d'écrire cette documentation")
await self.bot.say(embed=embed)
@_search.command(pass_context=True, name="aur")
async def search_aur(self, ctx, args):
await self.bot.send_typing(ctx.message.channel)
attends = await self.bot.say("_Je te cherche ça {} !_".format(ctx.message.author.mention))
erreur = 0
try:
html = urllib.request.urlopen("https://aur.archlinux.org/packages/" + args).read()
except:
erreur = 1
if erreur == 1:
await self.bot.delete_message(attends)
embed = discord.Embed(description=":sob: Je n'ai pas trouvé le packet mais j'ai lancé une petite recherche, tu y trouveras peut être ton bonheur ? https://aur.archlinux.org/packages/?K=" + args,url='https://aur.archlinux.org/')
embed.set_author(name="Aur.archlinux", url='https://aur.archlinux.org/', icon_url='http://outout.tech/tuxbot/arch.png')
embed.set_thumbnail(url='http://outout.tech/tuxbot/arch.png')
embed.set_footer(text="Pff même pas trouvé !")
await self.bot.say(embed=embed)
else:
await self.bot.delete_message(attends)
embed = discord.Embed(description="Et voila, j'ai trouvé la page sur le packet : https://aur.archlinux.org/packages/{0} ! \n Ca te dit un petit ``yaourt -S {0}`` ?".format(args), url='https://aur.archlinux.org/')
embed.set_author(name="Aur.archlinux", url='https://aur.archlinux.org/', icon_url='http://outout.tech/tuxbot/arch.png')
embed.set_thumbnail(url='http://outout.tech/tuxbot/arch.png')
embed.set_footer(text="C'est vrai que Aur est mieux qu'APT ^^")
await self.bot.say(embed=embed)
@_search.command(pass_context=True, name="wikipedia")
async def search_wikipedia(self, ctx, args):
"""Fait une recherche sur wikipd"""
try:
wait = await self.bot.say("_Je cherche..._")
results = wikipedia.search(args)
nbmr = 0
msg = ""
for value in results:
nbmr = nbmr + 1
msg = msg + "**{}**: {} \n".format(str(nbmr), value)
em = discord.Embed(title='Résultats de : ' + args, description = msg, colour=0x4ECDC4)
em.set_thumbnail(url = "https://upload.wikimedia.org/wikipedia/commons/2/26/Paullusmagnus-logo_%28large%29.png")
await self.bot.delete_message(wait)
final = await self.bot.say(embed=em)
list_emojis = ["1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣", "🔟"]
for emoji in list_emojis:
await self.bot.add_reaction(final, emoji)
res = await self.bot.wait_for_reaction(message=final, user=ctx.message.author)
for emoji in list_emojis:
num_emoji = list_emojis.index(emoji)
if res.reaction.emoji == emoji:
args_ = results[num_emoji]
try:
await self.bot.delete_message(final)
await self.bot.send_typing(ctx.message.channel)
wait = await self.bot.say(ctx.message.author.mention + " ah ok sympa cette recherche, je l'effectue de suite !")
wp = wikipedia.page(args_)
wp_contenu = wp.summary[:200] + "..."
em = discord.Embed(title='Wikipedia : ' + wp.title, description = "{} \n_Lien_ : {} ".format(wp_contenu, wp.url), colour=0x9B59B6)
em.set_author(name="Wikipedia", url='http://wikipedia.org', icon_url='https://upload.wikimedia.org/wikipedia/commons/2/26/Paullusmagnus-logo_%28large%29.png')
em.set_thumbnail(url = "https://upload.wikimedia.org/wikipedia/commons/2/26/Paullusmagnus-logo_%28large%29.png")
em.set_footer(text="Merci à eux de nous fournir une encyclopédie libre !")
await self.bot.delete_message(wait)
await self.bot.say(embed=em)
except wikipedia.exceptions.PageError:
await self.bot.say(":open_mouth: Une **erreur interne** est survenue, si cela ce reproduit contactez votre administrateur ou faites une Issue sur ``github`` !")
except UnboundLocalError:
await self.bot.say(":interrobang: Veuillez choisir une réaction valide !")
except DisambiguationError:
await self.bot.say(":open_mouth: Une **erreur interne** est survenue, si cela ce reproduit contactez votre administrateur ou faites une Issue sur ``github`` !")
except IndexError:
await self.bot.say(" :interrobang: Veuillez entrer un terme de recherche !")
def setup(bot):
bot.add_cog(Search(bot))

126
cogs/utility.py Normal file
View File

@ -0,0 +1,126 @@
from discord.ext import commands
from random import choice, shuffle
import random
import aiohttp
import asyncio
import time
import discord
import urllib.request, json
import datetime, pytz
class Utility:
"""Commandes utilitaires."""
def __init__(self, bot):
self.bot = bot
@commands.command()
async def clock(self, args):
"""Display hour in a country"""
args = args.upper()
then = datetime.datetime.now(pytz.utc)
form = '%H heures %M'
try:
argument = args[1]
if args == "MONTREAL":
utc = then.astimezone(pytz.timezone('America/Montreal'))
site = "http://ville.montreal.qc.ca/"
img = "https://upload.wikimedia.org/wikipedia/commons/e/e0/Rentier_fws_1.jpg"
country = "au Canada, Québec"
description = "Montréal est la deuxième ville la plus peuplée du Canada. Elle se situe dans la région du Québec"
elif args == "VANCOUVER":
utc = then.astimezone(pytz.timezone('America/Vancouver'))
site = "http://vancouver.ca/"
img = "https://upload.wikimedia.org/wikipedia/commons/f/fe/Dock_Vancouver.JPG"
country = "au Canada"
description = "Vancouver, officiellement City of Vancouver, est une cité portuaire au Canada"
elif args == "NEW-YORK" or args == "N-Y":
utc = then.astimezone(pytz.timezone('America/New_York'))
site = "http://www1.nyc.gov/"
img = "https://upload.wikimedia.org/wikipedia/commons/e/e3/NewYork_LibertyStatue.jpg"
country = "aux U.S.A."
description = "New York, est la plus grande ville des États-Unis en termes d'habitants et l'une des plus importantes du continent américain. "
elif args == "LOSANGELES" or args == "L-A" or args == "LA" or args == "LACITY":
utc = then.astimezone(pytz.timezone('America/Los_Angeles'))
site = "https://www.lacity.org/"
img = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/LA_Skyline_Mountains2.jpg/800px-LA_Skyline_Mountains2.jpg"
country = "aux U.S.A."
description = "Los Angeles est la deuxième ville la plus peuplée des États-Unis après New York. Elle est située dans le sud de l'État de Californie, sur la côte pacifique."
elif args == "PARIS":
utc = then.astimezone(pytz.timezone('Europe/Paris'))
site = "http://www.paris.fr/"
img = "https://upload.wikimedia.org/wikipedia/commons/a/af/Tour_eiffel_at_sunrise_from_the_trocadero.jpg"
country = "en France"
description = "Paris est la capitale de la France. Elle se situe au cœur d'un vaste bassin sédimentaire aux sols fertiles et au climat tempéré, le bassin parisien."
elif args == "BERLIN":
utc = then.astimezone(pytz.timezone('Europe/Berlin'))
site = "http://www.berlin.de/"
img = "https://upload.wikimedia.org/wikipedia/commons/9/91/Eduard_Gaertner_Schlossfreiheit.jpg"
country = "en Allemagne"
description = "Berlin est la capitale et la plus grande ville d'Allemagne. Située dans le nord-est du pays, elle compte environ 3,5 millions d'habitants. "
elif args == "BERN" or args == "ZURICH" or args == "BERNE":
utc = then.astimezone(pytz.timezone('Europe/Zurich'))
site = "http://www.berne.ch/"
img = "https://upload.wikimedia.org/wikipedia/commons/d/db/Justitia_Statue_02.jpg"
country = "en Suisse"
description = "Berne est la cinquième plus grande ville de Suisse et la capitale du canton homonyme. Depuis 1848, Berne est la « ville fédérale »."
elif args == "TOKYO":
utc = then.astimezone(pytz.timezone('Asia/Tokyo'))
site = "http://www.gotokyo.org/"
img = "https://upload.wikimedia.org/wikipedia/commons/3/37/TaroTokyo20110213-TokyoTower-01.jpg"
country = "au Japon"
description = "Tokyo, anciennement Edo, officiellement la préfecture métropolitaine de Tokyo, est la capitale du Japon."
elif args == "MOSCOU":
utc = then.astimezone(pytz.timezone('Europe/Moscow'))
site = "https://www.mos.ru/"
img = "https://upload.wikimedia.org/wikipedia/commons/f/f7/Andreyevsky_Zal.jpg"
country = "en Russie"
description = "Moscou est la capitale de la Fédération de Russie et la plus grande ville d'Europe. Moscou est situé sur la rivière Moskova. "
try:
if args == "LIST":
text = open('texts/clocks.md').read()
em = discord.Embed(title='Liste des Horloges', description=text, colour=0xEEEEEE)
await self.bot.say(embed=em)
else:
tt = utc.strftime(form)
em = discord.Embed(title='Heure à ' + args[1].title(), description="A [{}]({}) {}, Il est **{}** ! \n {} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_".format(str(args), site, str(country), str(tt), str(description)), colour=0xEEEEEE)
em.set_thumbnail(url = img)
await self.bot.say(embed=em)
except UnboundLocalError:
await self.bot.say("[**Erreur**] Ville inconnue, faites ``.clock list`` pour obtenir la liste des villes")
except IndexError:
await self.bot.say("[**Erreur**] Ville inconnue, faites ``.clock list`` pour obtenir la liste des villes")
@commands.command()
async def ytdiscover(self):
"""Random youtube channel"""
with open('texts/ytb.json') as js:
ytb = json.load(js)
clef = str(random.randint(0,12))
chaine = ytb["{}".format(clef)]
embed = discord.Embed(title=chaine['name'], url=chaine['url'],
description="**{}**, {} \n[Je veux voir ça]({})".format(chaine['name'], chaine['desc'], chaine['url']))
embed.set_thumbnail(url='https://outout.tech/tuxbot/yt.png')
await self.bot.say(embed=embed)
@commands.command(pass_context=True)
async def afk(self, ctx):
"""Away from keyboard"""
msgs = ["s'absente de discord quelques instants", "se casse de son pc", "va sortir son chien", "reviens bientôt", "va nourrir son cochon", "va manger des cookies", "va manger de la poutine", "va faire caca", "va faire pipi"]
msg = random.choice(msgs)
await self.bot.say("**{}** {}...".format(ctx.message.author.mention, msg))
@commands.command(pass_context=True)
async def back(self, ctx):
"""I'm back !"""
msgs = ["a réssuscité", "est de nouveau parmi nous", "a fini de faire caca", "a fini d'urine", "n'est plus mort", "est de nouveau sur son PC", "a fini de manger sa poutine", "a fini de danser", "s'est réveillé", "est de retour dans ce monde cruel"]
msg = random.choice(msgs)
await self.bot.say("**{}** {} !".format(ctx.message.author.mention, msg))
def setup(bot):
bot.add_cog(Utility(bot))

0
cogs/utils/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

58
cogs/utils/checks.py Normal file
View File

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
import discord.utils
from discord.ext import commands
def is_owner_check(message):
owner = message.author.id in ['171685542553976832', '163697401935298560', '88644904112128000', '92619860521005056', '273757386127441920'] ###ID's modo & admin
return owner # Owner of the bot
def is_owner(warn=True):
def check(ctx, warn):
owner = is_owner_check(ctx.message)
if not owner and warn:
print(ctx.message.author.name + " à essayer d'executer " + ctx.message.content)
return owner
owner = commands.check(lambda ctx: check(ctx, warn))
return owner
def check_permissions(ctx, perms):
msg = ctx.message
if is_owner_check(msg):
return True
ch = msg.channel
author = msg.author
resolved = ch.permissions_for(author)
return all(getattr(resolved, name, None) == value for name, value in perms.items())
def role_or_permissions(ctx, check, **perms):
if check_permissions(ctx, perms):
return True
ch = ctx.message.channel
author = ctx.message.author
if ch.is_private:
return False # can't have roles in PMs
role = discord.utils.find(check, author.roles)
return role is not None
def admin_or_permissions(**perms):
def predicate(ctx):
return role_or_permissions(ctx, lambda r: r.name == 'Bot Admin', **perms)
return commands.check(predicate)
def is_in_servers(*server_ids):
def predicate(ctx):
server = ctx.message.server
if server is None:
return False
return server.id in server_ids
return commands.check(predicate)

67
cogs/utils/config.py Normal file
View File

@ -0,0 +1,67 @@
import json
import os
import uuid
import asyncio
class Config:
"""The "database" object. Internally based on ``json``."""
def __init__(self, name, **options):
self.name = name
self.object_hook = options.pop('object_hook', None)
self.encoder = options.pop('encoder', None)
self.loop = options.pop('loop', asyncio.get_event_loop())
self.lock = asyncio.Lock()
if options.pop('load_later', False):
self.loop.create_task(self.load())
else:
self.load_from_file()
def load_from_file(self):
try:
with open(self.name, 'r') as f:
self._db = json.load(f, object_hook=self.object_hook)
except FileNotFoundError:
self._db = {}
async def load(self):
with await self.lock:
await self.loop.run_in_executor(None, self.load_from_file)
def _dump(self):
temp = '%s-%s.tmp' % (uuid.uuid4(), self.name)
with open(temp, 'w', encoding='utf-8') as tmp:
json.dump(self._db.copy(), tmp, ensure_ascii=True, cls=self.encoder, separators=(',', ':'))
# atomically move the file
os.replace(temp, self.name)
async def save(self):
with await self.lock:
await self.loop.run_in_executor(None, self._dump)
def get(self, key, *args):
"""Retrieves a config entry."""
return self._db.get(key, *args)
async def put(self, key, value, *args):
"""Edits a config entry."""
self._db[key] = value
await self.save()
async def remove(self, key):
"""Removes a config entry."""
del self._db[key]
await self.save()
def __contains__(self, item):
return item in self._db
def __getitem__(self, item):
return self._db[item]
def __len__(self):
return len(self._db)
def all(self):
return self._db

75
cogs/utils/formats.py Normal file
View File

@ -0,0 +1,75 @@
async def entry_to_code(bot, entries):
width = max(map(lambda t: len(t[0]), entries))
output = ['```']
fmt = '{0:<{width}}: {1}'
for name, entry in entries:
output.append(fmt.format(name, entry, width=width))
output.append('```')
await bot.say('\n'.join(output))
import datetime
async def indented_entry_to_code(bot, entries):
width = max(map(lambda t: len(t[0]), entries))
output = ['```']
fmt = '\u200b{0:>{width}}: {1}'
for name, entry in entries:
output.append(fmt.format(name, entry, width=width))
output.append('```')
await bot.say('\n'.join(output))
async def too_many_matches(bot, msg, matches, entry):
check = lambda m: m.content.isdigit()
await bot.say('There are too many matches... Which one did you mean? **Only say the number**.')
await bot.say('\n'.join(map(entry, enumerate(matches, 1))))
# only give them 3 tries.
for i in range(3):
message = await bot.wait_for_message(author=msg.author, channel=msg.channel, check=check)
index = int(message.content)
try:
return matches[index - 1]
except:
await bot.say('Please give me a valid number. {} tries remaining...'.format(2 - i))
raise ValueError('Too many tries. Goodbye.')
class Plural:
def __init__(self, **attr):
iterator = attr.items()
self.name, self.value = next(iter(iterator))
def __str__(self):
v = self.value
if v > 1:
return '%s %ss' % (v, self.name)
return '%s %s' % (v, self.name)
def human_timedelta(dt):
now = datetime.datetime.utcnow()
delta = now - dt
hours, remainder = divmod(int(delta.total_seconds()), 3600)
minutes, seconds = divmod(remainder, 60)
days, hours = divmod(hours, 24)
years, days = divmod(days, 365)
if years:
if days:
return '%s and %s ago' % (Plural(year=years), Plural(day=days))
return '%s ago' % Plural(year=years)
if days:
if hours:
return '%s and %s ago' % (Plural(day=days), Plural(hour=hours))
return '%s ago' % Plural(day=days)
if hours:
if minutes:
return '%s and %s ago' % (Plural(hour=hours), Plural(minute=minutes))
return '%s ago' % Plural(hour=hours)
if minutes:
if seconds:
return '%s and %s ago' % (Plural(minute=minutes), Plural(second=seconds))
return '%s ago' % Plural(minute=minutes)
return '%s ago' % Plural(second=seconds)

147
cogs/utils/maps.py Normal file
View File

@ -0,0 +1,147 @@
#!/bin/env python
# With credit to DanielKO
from lxml import etree
import datetime, re
import asyncio, aiohttp
NINTENDO_LOGIN_PAGE = "https://id.nintendo.net/oauth/authorize"
SPLATNET_CALLBACK_URL = "https://splatoon.nintendo.net/users/auth/nintendo/callback"
SPLATNET_CLIENT_ID = "12af3d0a3a1f441eb900411bb50a835a"
SPLATNET_SCHEDULE_URL = "https://splatoon.nintendo.net/schedule"
class Rotation(object):
def __init__(self):
self.start = None
self.end = None
self.turf_maps = []
self.ranked_mode = None
self.ranked_maps = []
@property
def is_over(self):
return self.end < datetime.datetime.utcnow()
def __str__(self):
now = datetime.datetime.utcnow()
prefix = ''
if self.start > now:
minutes_delta = int((self.start - now) / datetime.timedelta(minutes=1))
hours = int(minutes_delta / 60)
minutes = minutes_delta % 60
prefix = '**In {0} hours and {1} minutes**:\n'.format(hours, minutes)
else:
prefix = '**Current Rotation**:\n'
fmt = 'Turf War is {0[0]} and {0[1]}\n{1} is {2[0]} and {2[1]}'
return prefix + fmt.format(self.turf_maps, self.ranked_mode, self.ranked_maps)
# based on https://github.com/Wiwiweb/SakuraiBot/blob/master/src/sakuraibot.py
async def get_new_splatnet_cookie(username, password):
parameters = {'client_id': SPLATNET_CLIENT_ID,
'response_type': 'code',
'redirect_uri': SPLATNET_CALLBACK_URL,
'username': username,
'password': password}
async with aiohttp.post(NINTENDO_LOGIN_PAGE, data=parameters) as response:
cookie = response.history[-1].cookies.get('_wag_session')
if cookie is None:
print(req)
raise Exception("Couldn't retrieve cookie")
return cookie
def parse_splatnet_time(timestr):
# time is given as "MM/DD at H:MM [p|a].m. (PDT|PST)"
# there is a case where it goes over the year, e.g. 12/31 at ... and then 1/1 at ...
# this case is kind of weird though and is currently unexpected
# it could even end up being e.g. 12/31/2015 ... and then 1/1/2016 ...
# we'll never know
regex = r'(?P<month>\d+)\/(?P<day>\d+)\s*at\s*(?P<hour>\d+)\:(?P<minutes>\d+)\s*(?P<p>a\.m\.|p\.m\.)\s*\((?P<tz>.+)\)'
m = re.match(regex, timestr.strip())
if m is None:
raise RuntimeError('Apparently the timestamp "{}" does not match the regex.'.format(timestr))
matches = m.groupdict()
tz = matches['tz'].strip().upper()
offset = None
if tz == 'PDT':
# EDT is UTC - 4, PDT is UTC - 7, so you need +7 to make it UTC
offset = +7
elif tz == 'PST':
# EST is UTC - 5, PST is UTC - 8, so you need +8 to make it UTC
offset = +8
else:
raise RuntimeError('Unknown timezone found: {}'.format(tz))
pm = matches['p'].replace('.', '') # a.m. -> am
current_time = datetime.datetime.utcnow()
# Kind of hacky.
fmt = "{2}/{0[month]}/{0[day]} {0[hour]}:{0[minutes]} {1}".format(matches, pm, current_time.year)
splatoon_time = datetime.datetime.strptime(fmt, '%Y/%m/%d %I:%M %p') + datetime.timedelta(hours=offset)
# check for new year
if current_time.month == 12 and splatoon_time.month == 1:
splatoon_time.replace(current_time.year + 1)
return splatoon_time
async def get_splatnet_schedule(splatnet_cookie):
cookies = {'_wag_session': splatnet_cookie}
"""
This is repeated 3 times:
<span class"stage-schedule"> ... </span> <--- figure out how to parse this
<div class="stage-list">
<div class="match-type">
<span class="icon-regular-match"></span> <--- turf war
</div>
... <span class="map-name"> ... </span>
... <span class="map-name"> ... </span>
</div>
<div class="stage-list">
<div class="match-type">
<span class="icon-earnest-match"></span> <--- ranked
</div>
... <span class="rule-description"> ... </span> <--- Splat Zones, Rainmaker, Tower Control
... <span class="map-name"> ... </span>
... <span class="map-name"> ... </span>
</div>
"""
schedule = []
async with aiohttp.get(SPLATNET_SCHEDULE_URL, cookies=cookies, data={'locale':"en"}) as response:
text = await response.text()
root = etree.fromstring(text, etree.HTMLParser())
stage_schedule_nodes = root.xpath("//*[@class='stage-schedule']")
stage_list_nodes = root.xpath("//*[@class='stage-list']")
if len(stage_schedule_nodes)*2 != len(stage_list_nodes):
raise RuntimeError("SplatNet changed, need to update the parsing!")
for sched_node in stage_schedule_nodes:
r = Rotation()
start_time, end_time = sched_node.text.split("~")
r.start = parse_splatnet_time(start_time)
r.end = parse_splatnet_time(end_time)
tw_list_node = stage_list_nodes.pop(0)
r.turf_maps = tw_list_node.xpath(".//*[@class='map-name']/text()")
ranked_list_node = stage_list_nodes.pop(0)
r.ranked_maps = ranked_list_node.xpath(".//*[@class='map-name']/text()")
r.ranked_mode = ranked_list_node.xpath(".//*[@class='rule-description']/text()")[0]
schedule.append(r)
return schedule

212
cogs/utils/paginator.py Normal file
View File

@ -0,0 +1,212 @@
import asyncio
import discord
class CannotPaginate(Exception):
pass
class Pages:
"""Implements a paginator that queries the user for the
pagination interface.
Pages are 1-index based, not 0-index based.
If the user does not reply within 2 minutes then the pagination
interface exits automatically.
Parameters
------------
bot
The bot instance.
message
The message that initiated this session.
entries
A list of entries to paginate.
per_page
How many entries show up per page.
Attributes
-----------
embed: discord.Embed
The embed object that is being used to send pagination info.
Feel free to modify this externally. Only the description,
footer fields, and colour are internally modified.
permissions: discord.Permissions
Our permissions for the channel.
"""
def __init__(self, bot, *, message, entries, per_page=12):
self.bot = bot
self.entries = entries
self.message = message
self.author = message.author
self.per_page = per_page
pages, left_over = divmod(len(self.entries), self.per_page)
if left_over:
pages += 1
self.maximum_pages = pages
self.embed = discord.Embed()
self.paginating = len(entries) > per_page
self.reaction_emojis = [
('\N{BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}', self.first_page),
('\N{BLACK LEFT-POINTING TRIANGLE}', self.previous_page),
('\N{BLACK RIGHT-POINTING TRIANGLE}', self.next_page),
('\N{BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}', self.last_page),
('\N{INPUT SYMBOL FOR NUMBERS}', self.numbered_page ),
('\N{BLACK SQUARE FOR STOP}', self.stop_pages),
('\N{INFORMATION SOURCE}', self.show_help),
]
server = self.message.server
if server is not None:
self.permissions = self.message.channel.permissions_for(server.me)
else:
self.permissions = self.message.channel.permissions_for(self.bot.user)
if not self.permissions.embed_links:
raise CannotPaginate('Bot does not have embed links permission.')
def get_page(self, page):
base = (page - 1) * self.per_page
return self.entries[base:base + self.per_page]
async def show_page(self, page, *, first=False):
self.current_page = page
entries = self.get_page(page)
p = []
for t in enumerate(entries, 1 + ((page - 1) * self.per_page)):
p.append('%s. %s' % t)
self.embed.set_footer(text='Page %s/%s (%s entries)' % (page, self.maximum_pages, len(self.entries)))
if not self.paginating:
self.embed.description = '\n'.join(p)
return await self.bot.send_message(self.message.channel, embed=self.embed)
if not first:
self.embed.description = '\n'.join(p)
await self.bot.edit_message(self.message, embed=self.embed)
return
# verify we can actually use the pagination session
if not self.permissions.add_reactions:
raise CannotPaginate('Bot does not have add reactions permission.')
if not self.permissions.read_message_history:
raise CannotPaginate('Bot does not have Read Message History permission.')
p.append('')
p.append('Confused? React with \N{INFORMATION SOURCE} for more info.')
self.embed.description = '\n'.join(p)
self.message = await self.bot.send_message(self.message.channel, embed=self.embed)
for (reaction, _) in self.reaction_emojis:
if self.maximum_pages == 2 and reaction in ('\u23ed', '\u23ee'):
# no |<< or >>| buttons if we only have two pages
# we can't forbid it if someone ends up using it but remove
# it from the default set
continue
await self.bot.add_reaction(self.message, reaction)
async def checked_show_page(self, page):
if page != 0 and page <= self.maximum_pages:
await self.show_page(page)
async def first_page(self):
"""goes to the first page"""
await self.show_page(1)
async def last_page(self):
"""goes to the last page"""
await self.show_page(self.maximum_pages)
async def next_page(self):
"""goes to the next page"""
await self.checked_show_page(self.current_page + 1)
async def previous_page(self):
"""goes to the previous page"""
await self.checked_show_page(self.current_page - 1)
async def show_current_page(self):
if self.paginating:
await self.show_page(self.current_page)
async def numbered_page(self):
"""lets you type a page number to go to"""
to_delete = []
to_delete.append(await self.bot.send_message(self.message.channel, 'What page do you want to go to?'))
msg = await self.bot.wait_for_message(author=self.author, channel=self.message.channel,
check=lambda m: m.content.isdigit(), timeout=30.0)
if msg is not None:
page = int(msg.content)
to_delete.append(msg)
if page != 0 and page <= self.maximum_pages:
await self.show_page(page)
else:
to_delete.append(await self.bot.say('Invalid page given. (%s/%s)' % (page, self.maximum_pages)))
await asyncio.sleep(5)
else:
to_delete.append(await self.bot.send_message(self.message.channel, 'Took too long.'))
await asyncio.sleep(5)
try:
await self.bot.delete_messages(to_delete)
except Exception:
pass
async def show_help(self):
"""shows this message"""
e = discord.Embed()
messages = ['Welcome to the interactive paginator!\n']
messages.append('This interactively allows you to see pages of text by navigating with ' \
'reactions. They are as follows:\n')
for (emoji, func) in self.reaction_emojis:
messages.append('%s %s' % (emoji, func.__doc__))
e.description = '\n'.join(messages)
e.colour = 0x738bd7 # blurple
e.set_footer(text='We were on page %s before this message.' % self.current_page)
await self.bot.edit_message(self.message, embed=e)
async def go_back_to_current_page():
await asyncio.sleep(60.0)
await self.show_current_page()
self.bot.loop.create_task(go_back_to_current_page())
async def stop_pages(self):
"""stops the interactive pagination session"""
await self.bot.delete_message(self.message)
self.paginating = False
def react_check(self, reaction, user):
if user is None or user.id != self.author.id:
return False
for (emoji, func) in self.reaction_emojis:
if reaction.emoji == emoji:
self.match = func
return True
return False
async def paginate(self):
"""Actually paginate the entries and run the interactive loop if necessary."""
await self.show_page(1, first=True)
while self.paginating:
react = await self.bot.wait_for_reaction(message=self.message, check=self.react_check, timeout=120.0)
if react is None:
self.paginating = False
try:
await self.bot.clear_reactions(self.message)
except:
pass
finally:
break
try:
await self.bot.remove_reaction(self.message, react.reaction.emoji, react.user)
except:
pass # can't remove it so don't bother doing so
await self.match()

View File

@ -1,22 +0,0 @@
__author__ = "Maël — outout14"
__licence__ = "WTFPL Licence 2.0"
###########################
# TuxBot Config file #
###########################
## TOKEN
## Insert your DiscordAPP Token here
token = " "
##PREFIX
##Default prefix .
prefix = "."
##Authorized channel
op_channel = ["tuxbot-dev", "bot", "boat", "commandes"]
##Version information
## DONT TOUCH !
version = " Release 5.0 "

0
logs/NOT A EMPTY FOLDER Normal file
View File

View File

@ -1 +0,0 @@
Not a empty folder

595
main.py
View File

@ -1,595 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = "Maël — outout"
__licence__ = "WTFPL Licence 2.0"
#################
# IMPORTS #
#################
from botassets import *
from botassets.imports import *
client = discord.Client()
status = "dnd"
wikipedia.set_lang("fr")
###########################################
# #
# LOGGER #
# #
###########################################
from logging.handlers import RotatingFileHandler
logger = logging.getLogger()
logger.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s // [%(levelname)s] : %(message)s')
file_handler = RotatingFileHandler('logs/activity.log', 'a', 1000000, 1)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.info(' \n \n New TuxBot instance \n \n')
###########################################
# OPEN GAME FILE NAME #
###########################################
game = open('msg/game.txt').read()
#### SQL #####
conn = sqlite3.connect('tuxbot.db') #Connexion SQL
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS users(
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
userid TEXT,
username TEXT,
usermention TEXT,
os TEXT,
config TEXT,
useravatar TEXT,
userbirth TEXT,
cidate TEXT,
pays TEXT
)
""")# Creation table Utilisateur si premiere fois
conn.commit()
###########################################
# #
# ON_READY #
# #
###########################################
@client.event
async def on_ready():
logger.info('BOT READY !')
print("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-")
print("TuxBot " + version)
logger.log(logging.DEBUG, 'TuxBot ' + version)
print(" ")
print("Pret ! ")
print("Vous pouvez l'utiliser.")
await client.change_presence(game=discord.Game(name=game), status=discord.Status(status), afk=False) ## Game set in config.py
print("Jeu joué : " + game)
print("Pseudo : " + client.user.name)
print("ID : " + client.user.id)
logger.debug('Bot ID : ' + client.user.id)
print("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-")
###########################################
# #
# JOIN AND LEAVE #
# #
###########################################
@client.event
async def on_member_join(member):
logger.log(logging.INFO, member.name + ' joined the server !')
server = member.server
prv = await client.start_private_message(member)
welcome_msg = random.choice(arrays.wlcm_msgs)
if member.server.name == "Aide GNU/Linux-fr":
fmt = 'Bienvenue {0.mention} sur le suberbe serveur discord **' + member.server.name + '** ! Je te conseil de lire #regles pour commencer et te créer une carte d\'identité dans ``#bot`` grâce à la commande ``.ci-register`` et la personnaliser :smile: !'
else:
fmt = 'Bienvenue {0.mention} sur le discord **'+ member.server.name +'**, j\'espère que tu passeras un bon moment avec nous !' ##Multi-Server
await client.send_message(prv, fmt.format(member))
await client.send_message(member.server.default_channel, "**{0}**".format(welcome_msg.format(member)))
@client.event
async def on_member_remove(member):
adios_msg = random.choice(arrays.adios_msgs)
logger.log(logging.INFO, member.name + ' left the server !')
await client.send_message(member.server.default_channel, "**{0}**".format(adios_msg.format(member)))
###########################################
# #
# DELETE MESSAGE #
# #
###########################################
@client.event
async def on_message_delete(message):
if not message.channel.is_private and not message.author.bot:
msg_log = open('logs/deleted_msg.log', 'a')
date = time.localtime(time.time())
msg_log.write(str(message.author.name) + " (" + message.author.id + ")\n")
msg_log.write(" -> serveur : " + message.server.name + " \n")
msg_log.write(" -> date : " + str(time.strftime("%d %b %Y %H:%M:%S", date)) + "\n")
msg_log.write(" -> message : " + str(message.content) + "\n")
msg_log.write("--------------------------------------------------------------------------------------------------\n")
msg_log.close()
@client.event
async def on_message(message):
###########################################
# #
# CUSTOMS FUNCTIONS #
# BLOCKING AND ... #
# #
###########################################
roles = ["bot-commander", "poney"]
def cmd(cmd_name):
if not message.channel.is_private and not message.author.bot:
return message.content.startswith(prefix + cmd_name)
def authadmin():
role = message.author.roles
print("A")
try:
if str(role[0]) in roles or str(role[1]) in roles or str(role[2]) in roles or str(role[3]) in roles or str(role[4]) in roles:
return True
else:
return False
except IndexError:
return False
if message.channel.is_private and not message.author.bot:
await client.send_message(message.channel, "Désolé mais mon papa m'a dit de ne pas parler par Message Privé, viens plutot sur un serveur discord !")
###########################################
# #
# ADMIN COMMANDS #
# #
###########################################
if cmd("sendlogs"):
if authadmin:
wait = await client.send_message(message.channel, message.author.mention + " Le contenue du fichier log est entrain d'être envoyé... Veuillez patienter, cela peut prendre du temps !")
await client.send_file(message.author, fp="logs/activity.log", filename="activity.log", content="Voci mon fichier ``activity.log`` comme demandé !", tts=False)
await client.edit_message(wait, message.author.mention + " C'est bon vous venez de recevoir par message privé mon fichier de logs")
else:
await client.send_message(message.channel, "[**ERREUR**] Vous n'avez pas la permission d'executer cette commande")
elif cmd("say"): #Control
if authadmin():
args = message.content.split("say ")
try:
await client.send_message(message.channel, args[1])
logger.info(message.author.name + ' ordered TuxBot to say : ' + args[1])
await client.delete_message(message)
except IndexError:
await client.send_message(message.author, "**[ERREUR]** Merci de fournir le paramètre du message à dire, je ne suis pas dans ta tête !")
await client.delete_message(message)
else:
await client.send_message(message.channel, message.author.mention + "[**ERREUR**] Vous n'avez pas la permission d'executer cette commande")
elif cmd("clear"):
if authadmin:
try:
args = message.content.split("clear ")
argument = int(args[1])
argument = argument+1
logger.info(message.author.name + ' ordered TuxBot to remove ' + args[1] + ' messages')
deleted = await client.purge_from(message.channel, limit=argument)
await client.send_message(message.author, args[1] + " messages ont bien été supprimés")
except IndexError:
await client.send_message(message.author, "**[ERREUR]** Merci de fournir le paramètre du nombre de message à supprimer, je ne suis pas dans ta tête !")
await client.delete_message(message)
else:
await client.send_message(message.channel, message.author.mention + "[**ERREUR**] Vous n'avez pas la permission d'executer cette commande")
elif cmd("changegame"):
if authadmin:
args = message.content.split("changegame ")
try:
ngame = open('msg/game.txt','w')
ngame.write(args[1])
ngame.close()
rgame = open('msg/game.txt').read()
await client.change_presence(game=discord.Game(name=rgame), status=discord.Status(status), afk=False)
await client.send_message(message.author, "Mon jeu joué à bien été changé en : " + rgame)
await client.delete_message(message)
logger.info(message.author.name + ' changed the game played from tuxbot to : ' + args[1])
except IndexError:
await client.send_message(message.author, "**[ERREUR]** Merci de fournir le paramètre du jeu que je dois jouer, je ne suis pas dans ta tête !")
await client.delete_message(message)
else:
await client.send_message(message.channel, message.author.mention + "[**ERREUR**] Vous n'avez pas la permission d'executer cette commande")
###########################################
# #
# WWW COMMANDS #
# #
###########################################
elif cmd("search docubuntu"):
args_ = message.content.split(" ")
await client.send_typing(message.channel)
try:
msg = await client.send_message(message.channel, message.author.mention + " **Veuillez patienter**, Je suis entrain de parcourir le WorldWideWeb avec comme terme de recherche " + args_[2] + ", et ça peut prendre du temps ! ")
html = urllib.request.urlopen("https://doc.ubuntu-fr.org/" + args_[2]).read()
if "avez suivi un lien" in str(html):
await client.edit_message(msg, message.author.mention + " :sob: Oh non ! Cette page n'existe pas sur la doc ubuntu-fr. Mais vous pouvez commencer à la rédiger ! https://doc.ubuntu-fr.org/"+ args_[2])
else:
await client.edit_message(msg, message.author.mention + " :ok_hand: Trouvé ! Voici la page ramenant à votre recherche https://doc.ubuntu-fr.org/"+ args_[2])
except IndexError:
await client.edit_message(msg, message.author.mention + " **Erreur** : veuillez entrer un terme de recherche !")
elif cmd("search wikileaks"):
args_ = message.content.split(" ")
await client.send_typing(message.channel)
try:
msg = await client.send_message(message.channel, message.author.mention + " **Veuillez patienter**, Je suis entrain de parcourir le WorldWideWeb avec comme terme de recherche " + args_[2] + ", et ça peut prendre du temps ! ")
await client.send_typing(message.channel)
html = urllib.request.urlopen("https://search.wikileaks.org/?query=" + args_[2] + "#results").read()
await client.delete_message(msg)
if "0 results" in str(html):
await client.edit_message(msg, message.author.mention + " :sob: Oh non ! Aucun élément ne correspond de pres ou de loin a votre recherche.")
else:
await client.edit_message(msg, message.author.mention + " :ok_hand: Trouvé ! Le résultat de votre recherche est ici => https://search.wikileaks.org/?query=" + args_[2] + "#results")
except IndexError:
await client.edit_message(msg, message.author.mention + " **Erreur** : veuillez entrer un terme de recherche !")
elif cmd("search wikipedia"):
try:
args = message.content.split("search wikipedia")
wait = await client.send_message(message.channel, message.author.mention + " **Veuillez patienter**, Je suis entrain de parcourir Wikipedia avec comme terme de recherche " + args[1] + ", et ça peut prendre du temps ! ")
results = wikipedia.search(args[1])
nbmr = 0
msg = ""
for value in results:
nbmr = nbmr + 1
msg = msg + "**{}**: {} \n".format(str(nbmr), value)
em = discord.Embed(title='Résultats de : ' + args[1], description = msg, colour=0x4ECDC4)
em.set_thumbnail(url = "https://upload.wikimedia.org/wikipedia/commons/2/26/Paullusmagnus-logo_%28large%29.png")
await client.delete_message(wait)
final = await client.send_message(message.channel, embed=em)
for emoji in arrays.array_emoji:
await client.add_reaction(final, emoji)
res = await client.wait_for_reaction(message=final, user=message.author)
for emoji in arrays.array_emoji:
num_emoji = arrays.array_emoji.index(emoji)
if res.reaction.emoji == emoji:
args_ = results[num_emoji]
try:
await client.delete_message(final)
await client.send_typing(message.channel)
wait = await client.send_message(message.channel, message.author.mention + " **Veuillez patienter**, Je suis entrain de chercher sur Wikipedia " + args_ + ", et ça peut prendre du temps ! ")
wp = wikipedia.page(args_)
wp_contenu = wp.summary[:200] + "..."
em = discord.Embed(title='Wikipedia : ' + wp.title, description = "{} \n _Lien_ : {} ".format(wp_contenu, wp.url), colour=0x9B59B6)
em.set_thumbnail(url = "https://upload.wikimedia.org/wikipedia/commons/2/26/Paullusmagnus-logo_%28large%29.png")
em.set_footer(text = "Source : Wikipedia")
await client.delete_message(wait)
await client.send_message(message.channel, embed=em)
except wikipedia.exceptions.PageError:
await client.delete_message(msg)
await client.send_message(message.channel, message.author.mention + " **Erreur interne** : une erreur interne est survenue, si cela ce reproduit contactez votre administrateur ou faites une Issue sur github !")
except wikipedia.exceptions.DisambiguationError:
await client
except UnboundLocalError:
await client.send_message(message.channel, message.author.mention + " **Erreur** : veuillez choisir une réaction valide !")
except IndexError:
await client.send_message(message.channel, message.author.mention + " **Erreur** : veuillez entrer un terme de recherche !")
elif cmd("yt"):
await client.send_typing(message.channel)
chaineyt = random.choice(arrays.youtube)
ytname = chaineyt.split(",")
yturl = chaineyt.split(": ")
ytname = ytname[0]
text = "Je peux te conseiller cette chaîne youtube : " + chaineyt
em = discord.Embed(title='Youtube Discover', description=text, colour=0xCD201F)
em.set_author(name=ytname, icon_url="http://outout.tech/tuxbot_files/loading.gif")
msg = await client.send_message(message.channel, embed=em)
##GET ICON##
html_doc = urllib.request.urlopen(yturl[1]).read()
soup = BeautifulSoup(html_doc, "lxml")
getatr = soup.find_all("img", { "class" : "appbar-nav-avatar" }, ["src"])
getatr = str(getatr)
getatr = getatr.split('"')
em.set_author(name=ytname, icon_url=getatr[7])
await client.edit_message(msg, embed=em)
###########################################
# #
# BASICS COMMANDS #
# #
###########################################
if cmd("afk"):##AFK
msg = await client.send_message(message.channel, message.author.mention + " s'absente de discord quelques instants...")
await client.delete_message(message)
elif cmd("back"): ##BACK
await client.send_message(message.channel, message.author.mention + " est de retour parmi nous (il a recussité !)")
await client.delete_message(message)
elif cmd("ping"): #PING
t1 = time.perf_counter()
await client.send_typing(message.channel)
t2 = time.perf_counter()
result = round((t2-t1)*1000)
if int(result) >=200:
em = discord.Embed(title="Ping : " + str(result) + "ms", description="... c'est quoi ce ping !", colour=0xFF1111)
await client.send_message(message.channel, embed=em)
elif int(result) > 100 and int(result) < 200:
em = discord.Embed(title="Ping : " + str(result) + "ms", description="Ca va, ça peut aller, mais j'ai l'impression d'avoir 40 ans !", colour=0xFFA500)
await client.send_message(message.channel, embed=em)
elif int(result) <= 100:
em = discord.Embed(title="Ping : " + str(result) + "ms", description="Wow c'te vitesse de réaction, je m'épate moi-même !",colour=0x11FF11)
await client.send_message(message.channel, embed=em)
elif cmd("coin"): ##PIECE
piece = random.choice(["Pile", "Face", "... Heu, je l'ai perdu !", "Pile, j'ai gagné !", "Enfaite c'est quoi pile, c'est quoi face ?"])
await client.send_typing(message.channel)
msg = await client.send_message(message.channel, "La piece est retombé sur " + piece)
elif cmd("joke"): ##Joke
joke = random.choice(arrays.jokes)
await client.send_typing(message.channel)
msg = await client.send_message(message.channel, message.author.mention + " " + joke)
elif cmd("ethylotest"):
resultat = random.choice(arrays.policier)
await client.send_typing(message.channel)
msg = await client.send_message(message.channel, message.author.mention + resultat)
elif cmd('randomcat'): ##Cat
r = requests.get('http://random.cat/meow.php')
await client.send_message(message.channel, message.author.mention + " " + r.json()['file'])
elif cmd('pokemon'): ##Pokemon
await client.send_typing(message.channel)
poke1 = random.choice(arrays.pokemon)
poke2 = random.choice(arrays.pokemon)
win = random.choice([str(poke1),str(poke2)])
msg1 = await client.send_message(message.channel, '**Le combat Commence !**')
msg2 = await client.send_message(message.channel, '📢 **Présentateur** : Les combatants sont : ' + str(poke1) + ' Contre ' + str(poke2))
msg3 = await client.send_message(message.channel, '*Narateur : Le combat se déroule...*')
await client.send_typing(message.channel)
await asyncio.sleep(5)
msg4 = await client.send_message(message.channel, '**📢 Présentateur** : Le gagnant est..... ')
await client.send_typing(message.channel)
await asyncio.sleep(1)
msg5 = await client.send_message(message.channel, '**📢 Présentateur** : **' + str(win) + '**')
if cmd("servers-list"):
nbmr = 0
msg = ""
for serveur in list(client.servers):
nbmr = nbmr + 1
msg = msg + "=> **{}** \n".format(serveur.name)
msg = msg + "{} se trouve sur **{} serveur(s)** au total !".format(client.user.name, nbmr)
em = discord.Embed(title='Liste des serveurs où se trouve ' + client.user.name, description=msg, colour=0x36D7B7)
em.set_author(name=client.user.name, icon_url=client.user.avatar_url)
await client.send_message(message.channel, embed=em)
elif cmd("count-members"):
nbmr = 0
for name in list(client.get_all_members()):
nbmr = nbmr + 1
msg = "Il y'a **{} membres** sur le serveur Discord **{}**".format(nbmr, message.server.name)
em = discord.Embed(title='Compteur de membres', description=msg, colour=0x9A12B3)
await client.send_message(message.channel, embed=em)
###########################################
# #
# CLOCK #
# #
###########################################
elif cmd('clock'):
args = message.content.split("clock ")
args = [element.upper() for element in args]
args_ = [element.lower() for element in args]
then = datetime.datetime.now(pytz.utc)
form = '%H heures %M'
try:
argument = args[1]
if args[1] == "MONTREAL":
utc = then.astimezone(pytz.timezone('America/Montreal'))
site = "http://ville.montreal.qc.ca/"
img = "https://upload.wikimedia.org/wikipedia/commons/e/e0/Rentier_fws_1.jpg"
country = "au Canada, Québec"
description = "Montréal est la deuxième ville la plus peuplée du Canada. Elle se situe dans la région du Québec"
elif args[1] == "VANCOUVER":
utc = then.astimezone(pytz.timezone('America/Vancouver'))
site = "http://vancouver.ca/"
img = "https://upload.wikimedia.org/wikipedia/commons/f/fe/Dock_Vancouver.JPG"
country = "au Canada"
description = "Vancouver, officiellement City of Vancouver, est une cité portuaire au Canada"
elif args[1] == "NEW-YORK" or args[1] == "N-Y":
utc = then.astimezone(pytz.timezone('America/New_York'))
site = "http://www1.nyc.gov/"
img = "https://upload.wikimedia.org/wikipedia/commons/e/e3/NewYork_LibertyStatue.jpg"
country = "aux U.S.A."
description = "New York, est la plus grande ville des États-Unis en termes d'habitants et l'une des plus importantes du continent américain. "
elif args[1] == "LOSANGELES" or args[1] == "L-A" or args[1] == "LA" or args[1] == "LACITY":
utc = then.astimezone(pytz.timezone('America/Los_Angeles'))
site = "https://www.lacity.org/"
img = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/LA_Skyline_Mountains2.jpg/800px-LA_Skyline_Mountains2.jpg"
country = "aux U.S.A."
description = "Los Angeles est la deuxième ville la plus peuplée des États-Unis après New York. Elle est située dans le sud de l'État de Californie, sur la côte pacifique."
elif args[1] == "PARIS":
utc = then.astimezone(pytz.timezone('Europe/Paris'))
site = "http://www.paris.fr/"
img = "https://upload.wikimedia.org/wikipedia/commons/a/af/Tour_eiffel_at_sunrise_from_the_trocadero.jpg"
country = "en France"
description = "Paris est la capitale de la France. Elle se situe au cœur d'un vaste bassin sédimentaire aux sols fertiles et au climat tempéré, le bassin parisien."
elif args[1] == "BERLIN":
utc = then.astimezone(pytz.timezone('Europe/Berlin'))
site = "http://www.berlin.de/"
img = "https://upload.wikimedia.org/wikipedia/commons/9/91/Eduard_Gaertner_Schlossfreiheit.jpg"
country = "en Allemagne"
description = "Berlin est la capitale et la plus grande ville d'Allemagne. Située dans le nord-est du pays, elle compte environ 3,5 millions d'habitants. "
elif args[1] == "BERN" or args[1] == "ZURICH" or args[1] == "BERNE":
utc = then.astimezone(pytz.timezone('Europe/Zurich'))
site = "http://www.berne.ch/"
img = "https://upload.wikimedia.org/wikipedia/commons/d/db/Justitia_Statue_02.jpg"
country = "en Suisse"
description = "Berne est la cinquième plus grande ville de Suisse et la capitale du canton homonyme. Depuis 1848, Berne est la « ville fédérale »."
elif args[1] == "TOKYO":
utc = then.astimezone(pytz.timezone('Asia/Tokyo'))
site = "http://www.gotokyo.org/"
img = "https://upload.wikimedia.org/wikipedia/commons/3/37/TaroTokyo20110213-TokyoTower-01.jpg"
country = "au Japon"
description = "Tokyo, anciennement Edo, officiellement la préfecture métropolitaine de Tokyo, est la capitale du Japon."
elif args[1] == "MOSCOU":
utc = then.astimezone(pytz.timezone('Europe/Moscow'))
site = "https://www.mos.ru/"
img = "https://upload.wikimedia.org/wikipedia/commons/f/f7/Andreyevsky_Zal.jpg"
country = "en Russie"
description = "Moscou est la capitale de la Fédération de Russie et la plus grande ville d'Europe. Moscou est situé sur la rivière Moskova. "
try:
if args[1] == "LIST":
await client.send_typing(message.channel)
text = open('msg/clocks.md').read()
em = discord.Embed(title='Liste des Horloges', description=text.format(prefix), colour=0xEEEEEE)
await client.send_message(message.channel, embed=em)
else:
tt = utc.strftime(form)
em = discord.Embed(title='Heure à ' + args_[1].title(), description="A [{}]({}) {}, Il est **{}** ! \n {} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_".format(str(args[1]), site, str(country), str(tt), str(description)), colour=0xEEEEEE)
em.set_thumbnail(url = img)
await client.send_message(message.channel, embed=em)
except UnboundLocalError:
await client.send_message(message.channel, message.author.mention + " **[ERREUR]** Ville inconnue, ``.clock list`` pour afficher les villes disponibles !")
except IndexError:
await client.send_message(message.channel, message.author.mention + " **[ERREUR]** Veuillez sélectionner une ville dans ``.clock list`` !")
###################
# IDENTIY SYSTEM #
###################
elif cmd("ci-register"):
cursor.execute("""INSERT INTO users(userid, username, usermention, useravatar, userbirth, cidate) VALUES(?, ?, ?, ?, ?, ?)""", (message.author.id, message.author.name, message.author.mention, message.author.avatar_url, message.author.created_at, message.timestamp))
conn.commit()
await client.send_message(message.channel, message.author.mention + "> **Votre carte d'intentité à été enregistrée !** Pour plus d'informations sur le système de carte d'indentité, tapez la commande ``{}ci-info`` !".format(prefix))
elif cmd("ci-setos"):
try:
args = message.content.split("ci-setos ")
cursor.execute("""UPDATE users SET os = ? WHERE usermention = ?""", (args[1], message.author.mention))
conn.commit()
await client.send_message(message.channel, message.author.mention + " l'information à bien été modifié sur votre carte d'identité !")
except IndexError:
await client.send_message(message.channel, message.author.mention + " [**ERREUR**] : Veuillez argumenter la commande !")
elif cmd("ci-setconf"):
try:
args = message.content.split("ci-setconf ")
cursor.execute("""UPDATE users SET config = ? WHERE usermention = ?""", (args[1], message.author.mention))
conn.commit()
await client.send_message(message.channel, message.author.mention + " l'information à bien été modifié sur votre carte d'identité !")
except IndexError:
await client.send_message(message.channel, message.author.mention + " [**ERREUR**] : Veuillez argumenter la commande !")
elif cmd("ci-setnation"):
try:
args = message.content.split("ci-setnation ")
cursor.execute("""UPDATE users SET pays = ? WHERE usermention = ?""", (args[1], message.author.mention))
conn.commit()
await client.send_message(message.channel, message.author.mention + " l'information à bien été modifié sur votre carte d'identité !")
except IndexError:
await client.send_message(message.channel, message.author.mention + " [**ERREUR**] : Veuillez argumenter la commande !")
elif cmd("ci-info"):
cinfomd = open('msg/ci-info.md').read()
em = discord.Embed(title='Aide sur la carte d\'identité', description=cinfomd.format(prefix), colour=0xDEADBF)
await client.send_message(message.channel, embed=em)
elif cmd("ci"):
try:
args = message.content.split("ci ")
cursor.execute("""SELECT userid, username, os, usermention, useravatar, userbirth, cidate, config, pays FROM users WHERE usermention=?""", (args[1],))
result = cursor.fetchone()
if not result:
await client.send_message(message.channel, message.author.mention + "> Désolé mais {} n'a pas fait enregistrer sa Carte d'indentité".format(args[1]))
else:
userid = result[0]
username = result[1]
if not result[2]:
os = "Non renseigné"
else:
os = result[2]
if not result[7]:
config = "Non renseigné"
else:
config = result[7]
if not result[8]:
pays = "Non renseigné"
else:
pays = result[8]
useravatar = result[4]
userbirth = result[5]
cidate = result[6]
userbirth = userbirth.split(" ")
cidate = cidate.split(" ")
em_content = open('msg/identity.md').read()
em = discord.Embed(title='Carte d\'Identité de '+ username, description=em_content.format(userid, username, os, useravatar, userbirth[0], cidate[0], config, pays), colour=0xDEADBF)
em.set_author(name=username, icon_url=useravatar)
await client.send_message(message.channel, embed=em)
except IndexError:
await client.send_message(message.channel, message.author.mention + " [**ERREUR**] : Veuillez argumenter la commande !")
###########################################
# #
# HELP AND FIX COMMANDS #
# #
###########################################
elif cmd('help'): ##HELP
await client.send_typing(message.channel)
text = open('msg/help.md').read()
em = discord.Embed(title='Liste des Commandes', description=text.format(prefix), colour=0x89C4F4)
await client.send_message(message.channel, embed=em)
elif cmd("info"): ##info
text = open('msg/info.md').read()
em = discord.Embed(title='Informations sur ' + client.user.name, description=text, colour=0x89C4F9)
await client.send_message(message.channel, embed=em)
elif cmd('search help'): ##Search
text = open('msg/search.md').read()
em = discord.Embed(title='Sites de recherche', description=text.format(prefix), colour=0x4ECDC4)
await client.send_message(message.channel, embed=em)
elif cmd('github'): ##Link to github
await client.send_typing(message.channel)
text = "How tu veux voir mon repos Github pour me disséquer ? Pas de soucis ! Je suis un Bot, je ne ressens pas la douleur !\n https://github.com/outout14/tuxbot-bot"
em = discord.Embed(title='Repos TuxBot-Bot', description=text, colour=0xE9D460)
em.set_author(name='Outout', icon_url="https://avatars0.githubusercontent.com/u/14958554?v=3&s=400")
await client.send_message(message.channel, embed=em)
###########################################
# #
# AUTOMATICS FUNCTIONS #
# #
###########################################
if re.search(r'^(bonjour |salut |hello |bjr |slt |s\'lut)?([^ ]+ ){0,3}(qui s\'y conna(î|i)(t|s)|des gens|quelqu\'un|qqun|des personnes|du monde s\'y connait)[^\?]+\?$', message.content):
await client.send_message(message.channel, ":question: N'hésite pas à poser ta question directement " + message.author.mention + ", il n'est pas utile de demander si quelqu'un connait quelque chose avant.")
if message.content == message.content.upper() and not message.author.bot:
if len(message.content) > 5:
await client.send_message(message.channel, message.author.mention + " pas que des capitales dans ton message quand même !")
client.run(token)

View File

@ -1,8 +0,0 @@
La carte d'identité est un petit système dans tuxbot permetant de vous démarquer de vos amis en ayant la possibilité d'y renseigner plusieurs informations !
**Liste des commandes : **
-> {0}ci _@pseudo_ : Affiche la carte d'identité de _pseudo_
-> {0}ci-register : Vous enregistre dans la base de donnée des cartes d'identité
-> {0}ci-setos _nom de l'os_ : Défini le système d'exploitation (affiché sur la CI)
-> {0}ci-setconf _votre configuration pc_ : Défini la configuration de votre ordinateur (affiché sur la CI)
-> {0}ci-setnation : Défini votre Pays (affiché sur la CI)

View File

@ -1 +0,0 @@
passer une batterie de test

View File

@ -1,36 +0,0 @@
**Commandes diverses** :
-> {0}info : affiche des informations sur le bot
-> {0}help : affiche l'aide
-> {0}search help : affiche l'aide sur les commandes de recherche
-> {0}ci-info : affiche l'aide et des infos sur le système de carte d'identité
-> {0}clock list: affiche la liste des horloges des villes
-> {0}ping : Ping le bot
-> {0}github : Affiche le repos Github du Bot :heart:
**Commandes utilitaires**
-> {0}afk : signaler son absence
-> {0}back : signaler son retour
-> {0}clock _ville_: Affiche l'heure et quelques infos sur la ville en question
-> {0}ytdiscover : découvrir des chaines youtube
-> {0}servers-list : liste les serveurs où se trouve le bot
**Commandes Funs**
-> {0}joke : affiche une blague (au hasard)
-> {0}ethylotest : simule un ethylotest détraqué (au hasard)
-> {0}pokemon : Lance un combat de pokémons (au hasard)
-> {0}coin : fait un pile ou face
-> {0}randomcat : affiche des image de chats :heart:
**Commandes Carte d'Identité**
-> {0}ci _@pseudo_ : Affiche la carte d'identité de _pseudo_
-> {0}ci-register : Vous enregistre dans la base de donnée des cartes d'identité
-> {0}ci-setos _nom de l'os_ : Défini le système d'exploitation (affiché sur la CI)
-> {0}ci-setconf _votre configuration pc_ : Défini la configuration de votre ordinateur (affiché sur la CI)
-> {0}ci-setnation : Défini votre Pays (affiché sur la CI)
** Commandes d'administration **
-> {0}say _votre message_ : fait le bot écrire
-> {0}clear _nombre_ : Supprime _nombre_ de messages
-> {0}changegame _votre texte_ : Change le jeu joué par le Bot
-> {0}sendlogs : Envoie le fichier de Log du bot par MP

View File

@ -1,9 +0,0 @@
**ID** : {0}
**Nom** : {1}
**Système d'exploitation** : {2}
**Configuration Système** : {6}
**Lien vers avatar** : [Cliquer pour accèder]({3})
**Date de naissance** : {4}
**Pays** : {7}
_Date de fabrication de la carte : {5}_

View File

@ -1,21 +0,0 @@
==> Développement :
└> Outout : [outout.tech](https://outout.tech/)
└> Romain : [son github](https://github.com/Rom194)
└> Langage : [Python](http://www.python.org/)
└> Api : [discord.py](https://github.com/Rapptz/discord.py)
==> Serveur de Test:
└> Ordinateur de Outout sous [Ubuntu 16.04 LTS](http://releases.ubuntu.com/16.04/)
└> Version de Python : [3.5.2](http://www.python.org/)
==> Serveur de Prod :
└> Machine : [RaspberryPi3](https://www.raspberrypi.org) sous Debain
└> Version de Python : [3.5](http://www.python.org/)
==> Contact :
└> Discord : Outout#8406
└> Mèl : outout@linuxmail.org
==> Serveur Discord d'Origine :
└> Aide GNU/Linux-Fr : [rejoindre](https://discord.gg/B5TzW7x)

View File

@ -1 +0,0 @@

6
params.json Normal file
View File

@ -0,0 +1,6 @@
{
"token": "token",
"bots_key": "don't touch",
"client_id": "client id!",
"carbon_key": "don't touch"
}

39
readme.md Normal file
View File

@ -0,0 +1,39 @@
# Titre du projet
[![forthebadge](http://forthebadge.com/images/badges/contains-cat-gifs.svg)](http://forthebadge.com)
TuxBot, un bot discord écrit en Python.
Ici se trouve le code source de ce bot proventant du serveur Discord "Aide GNU/Linux-Fr", il à été créé spécialement pour ce discord, si vous souhaitez l'utiliser il vous faudra modifier ``settings.json`` et ``cogs/utils/checks.py`` ;)
### Pré-requis
Il vous faut :
- Un ordinateur sous **linux** avec une connexion à l'internet
- Python3.5 ou +
- Installer ``requirements.txt`` (avec ``pip install -r requirements.txt`` par ex)
### Installation
Une fois les prérequis installés et les paramètres édités placez vous dans le repertoire du bot et lancez ``bot.py`` avec python3 (ex: ``python3 bot.py``)
## Démarrage
Placez vous dans le repertoire du bot et lancez ``bot.py`` avec python3 (ex: ``python3 bot.py``)
## Fabriqué avec
* [PyCharm](https://www.jetbrains.com/pycharm/) - Editeur de texte payant :3
* [discord.py](https://github.com/Rapptz/discord.py) - API Python pour discord
## Versions
Liste des versions : [Cliquer pour afficher](https://github.com/outout14/tuxbot-bot/tags)
## Auteurs
* **Maël** _alias_ [@outout14](https://github.com/outout14)
* **Romain** _alias_ [Romain le malchanceux](https://github.com/Rom194)
## License
Ce projet est sous licence ``WTFTPL`` - voir le fichier [LICENSE.md](LICENSE.md) pour plus d'informations

View File

@ -1,4 +0,0 @@
@ECHO off
color f8
title TuxBOT / Windows
CMD /k python main.py

View File

@ -2,4 +2,4 @@
title="{TuxBot} - Unix Commander"
echo -e '\033]2;'$title'\007'
python3 main.py
python3 bot.py

9
texts/ci-info.md Normal file
View File

@ -0,0 +1,9 @@
La carte d'identité est un petit système dans tuxbot permetant de vous démarquer de vos amis en ayant la possibilité d'y renseigner plusieurs informations !
**Liste des commandes : **
-> ci : Affiche l'aide sur les cartes d'identité
-> ci show _@pseudo_ : Affiche la carte d'identité de _pseudo_
-> ci register : Vous enregistre dans la base de donnée des cartes d'identité
-> ci setos _nom de l'os_ : Défini le système d'exploitation
-> ci setconfig _votre configuration pc_ : Défini la configuration de votre ordinateur
-> ci setcountry : Défini votre Pays

View File

@ -1,5 +1,5 @@
_Pour utiliser les Horloges utilisez la commande : **{0}clock **nom de l'horloge_
_Pour utiliser les Horloges utilisez la commande : **clock **nom de l'horloge_
-> Montreal (Canada, QC)
-> Vancouver (Canada, BC)
-> New-York / N-Y (U.S.A.)

36
texts/help.md Normal file
View File

@ -0,0 +1,36 @@
**Commandes diverses** :
-> info : Affiche des informations sur le bot
-> help : Affiche ce message
-> ci : Affiche l'aide et des infos sur le système de carte d'identité
-> clock list: Affiche la liste des horloges des villes
-> ping : Ping le bot
-> github : Affiche le repos Github du Bot :heart:
**Commandes utilitaires**
-> afk : Signaler son absence
-> back : Signaler son retour
-> clock _ville_: Affiche l'heure et quelques infos sur la ville en question
-> ytdiscover : Découvrir des chaines youtube
-> search _site_ _contenu_ : Fait une recherche sur un site (.search pour plus d'infos)
-> avatar _@pseudo_ : Récupère l'avatar de _@pseudo_
**Commandes Funs**
-> joke : Affiche une blague aléatoire
-> ethylotest : Simule un ethylotest détraqué
-> pokemon : Lance un combat de pokémons aléatoires
-> coin : Fait un pile ou face
-> randomcat : Affiche des image de chats :3
**Commandes Carte d'Identité**
-> ci : Affiche l'aide sur les cartes d'identité
-> ci show _@pseudo_ : Affiche la carte d'identité de _pseudo_
-> ci register : Vous enregistre dans la base de donnée des cartes d'identité
-> ci setos _nom de l'os_ : Défini le système d'exploitation
-> ci setconfig _votre configuration pc_ : Défini la configuration de votre ordinateur
-> ci setcountry : Défini votre Pays
** Commandes d'administration **
-> say _votre message_ : fait le bot écrire
-> clear _nombre_ : Supprime _nombre_ de messages

18
texts/info.md Normal file
View File

@ -0,0 +1,18 @@
==> **Développement** :
└> Outout : [outout.tech](https://outout.tech/)
└> Romain : [son github](https://github.com/Rom194)
└> Langage : [Python3](http://www.python.org/)
└> Api : [discord.py {3}](https://github.com/Rapptz/discord.py)
└> En se basant sur : [RobotDanny](https://github.com/Rapptz/RoboDanny)
==> **Hébergé sur "{2}"**:
└> OS : {0}
└> Version de Python : {1}
==> **Contact** :
└> Discord : Outout#8406
└> Mail : [outout@linuxmail.org](mailto:outout@linuxmail.org)
==> **Serveur Discord d'Origine** :
└> Aide GNU/Linux-Fr : [rejoindre](https://discord.gg/B5TzW7x)

14
texts/jokes.json Normal file
View File

@ -0,0 +1,14 @@
{
"1": {"content": "Les hyperboles sa sert à manger des hyper-soupes :3 (Lawl!)", "author": "Crumble14 (bukkit.fr)"},
"2": {"content": "Le comble de Windows, cest que pour larrêter, il faut cliquer sur démarrer.", "author": "Keke142 (bukkit.fr)"},
"3": {"content": "Chrome: On est le 8 avril 2016 13h02 \n Safari: On est le 8 avril 2016 12h02 \n Internet Explorer: On est le... **[Internet Explorer a cessé de fonctionner, veuillez redémarrer votre machine]**", "author": "NyoSan"},
"4": {"content": "Il y a 10 types de personnes dans le monde, ceux qui comprennent le binaire et les autres.", "author": "Dartasen (bukkit.fr)"},
"5": {"content": "C'est une requête SQL qui rentre dans un bar et qui s'adresse à deux tables \"Puis-je vous joindre ?\".\"", "author": "Dartasen (bukkit.fr)"},
"6": {"content": "Combien de développeurs faut-il pour remplacer une ampoule grillée ? Aucun, c'est un problème Hardware.", "author": "Dartasen (bukkit.fr)"},
"7": {"content": "Tu sais que tu as affaire à un développeur quand ça ne le gêne pas d'avoir un String dans l'Array.", "author": "Dartasen (bukkit.fr)"},
"8": {"content": "Pourquoi y'a pas d'adresse windows ou linux ? Si y'a l'addresse mac !", "author": "Antho"},
"9": {"content": "Les appareils apple ont ils une adresse personnalisée ?", "author": "Outout"},
"10": {"content": "Le 1er janvier 1970 c'est le jour où il y a eu le plus de plantages. (cf : http://bit.ly/2rArLVe)", "author": "NyoSan"},
"11": {"content": "Pourquoi est-ce que les girafes aiment magasiner à bas prix? Tout est une question de cou.", "author": "Maxx_Qc (bukkit.fr)"},
"12": {"content": "``Même éteint le hackeur peut pirater l'ordi`` \"Le SuperGeek tournant sous Ubuntu (ou Windows)\"", "author": "Outout"}
}

1
texts/pokemons.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
_Attention ! : entrez vos termes de recherche sans espaces !_
Pour effectuer une recherche utilisez la commande ``{0}search site de recherche terme de la recherche``
-> [**wikileaks**](https://wikileaks.org) : Effectuer une recherche sur WikiLeaks, une organisation non gouvernemantale dont l'objectif premier est de publier des documents.
Pour effectuer une recherche utilisez la commande ``.search {site_de_recherche} {termes_recherche}``
-> [**docubuntu**](https://doc.ubuntu-fr.org) : Effectuer une recherche sur un paquet dans la Documentation du site ubuntu-fr.org.
-> [**wikipedia**](https://fr.wikipedia.org) : Effectuer une recherche sur l'encyclopédie libre Wikipedia en Français !
-> [**aur.archlinux**](https://aur.archlinux.org) : Effectuer une recherche sur Archlinux Aur !

15
texts/ytb.json Normal file
View File

@ -0,0 +1,15 @@
{
"1": {"name": "KickSama", "desc": "Des dessins annimés sympatiques par un jeune !", "url": "https://www.youtube.com/user/TheKickGuy"},
"2": {"name": "U=RI", "desc": "Des vidéos interessantes sur l'électricité dont des tutoriels !", "url": "https://www.youtube.com/channel/UCVqx3vXNghSqUcVg2nmegYA"},
"3": {"name": "Outout", "desc": "Outout, chaine vraiment nul et peu alimenté par mon créateur...", "url": "https://www.youtube.com/channel/UC2XpYyT5X5tq9UQpXdc1JaQ"},
"4": {"name": "SuperJDay64", "desc": "Des LetsPlay sur Nintendo64 avec beaucoup de plombiers moustachus !", "url": "https://www.youtube.com/channel/UCjkQgODdmhR9I2TatJZtGSQ/"},
"5": {"name": "Monsieur Plouf", "desc": "Vidéos comiques de critiques de jeux AAA avec un décors assez spécial !", "url": "https://www.youtube.com/channel/UCrt_PUTF9LdJyuDfXweHwuQ"},
"6": {"name": "MaxEstLa", "desc": "Petite chaîne bien _sympatique_ sur la réaction de vidéos malsaine ! Très éducative x)", "url": "https://www.youtube.com/channel/UCsk9XguwTfgbenCZ4AlIcYQ"},
"7": {"name": "Met-Hardware", "desc": "Chaine youtube sur l'hardware et des let's play bien sypatique !", "url": "https://www.youtube.com/channel/UC7rse81OttysA1m1yn_f-OA"},
"8": {"name": "ElectronikHeart", "desc": "~~Test de produits de merde ~~ L'informatique sous un angle différent et agréable", "url": "https://www.youtube.com/user/ElectronikHeart"},
"9": {"name": "Caljbeut", "desc": "Cartoon Trash ! Dessins annimés par un ancien de l'armée sur la politique et d'autre sujets ! **On est pas la pour rigoler**", "url": "https://www.youtube.com/channel/UCNM-UkIP1BL5jv9ZrN5JMCA"},
"10": {"name": "Autodisciple", "desc": "Defis, Bitcoins, Geek, la vie quoi ! Sans oublier des défis de 30 Jours !", "url": "https://www.youtube.com/channel/UCDMxcev7u9Nf7KMJuyIm-BA"},
"11": {"name": "CineAstuces", "desc": "Techniques, metiers du cinema, reportages et autres en rapport avec la cinématographie !", "url": "https://www.youtube.com/channel/UC--84qgkrqqqYivuuXuQIQg"},
"12": {"name": "Epic Teaching of the History", "desc": "L'Histoire c'est hyper méga giga ultra _(j'ai pas été payé)_ drôle avec RaAak le renard ! ", "url": "https://www.youtube.com/channel/UCHwd4qMCzN4A2r6piZxTl4A"}
}