Code Monkey home page Code Monkey logo

discord-bot's Introduction

GitHub is maintained Deploy

Contributors GitHub last commit GitHub last release Github last prerelease

Discord-Bot

A Discord bot that you can use as your own.
Built with a robust structure, seamless error handling, and easy configuration. Configure and edit effortlessly for a personalized experience.

Table of content

About the project

This discord bot was made for an IT School in 2020. It has a lot of features including all the latest features from discord.py. Made by student(s) for students.

Major features

  • Administrative Tools
    • Custom prefix per guild
    • Invite tracker
  • Developement & Tools
    • ANSI color support
    • Dynamic structure (Does not require a reboot to apply changes in code & files)
    • Database support (SQL)
    • Error handling
    • Image processing
    • Logging
    • Multiple configs
    • Metrics about usage of the bot
    • Powerful, dev & debuging commands
    • Utility functions
    • Socket communication system
  • Discord support
  • User Interaction
    • Custom Help command
    • Dynamic Starboard
    • Language detector & Translation
    • Private text channel on demand (cog: privatetext)
    • Private vocal channel on demand (cog: privatevocal)
    • Reddit posts listner
  • And more..

Built with

Note

More about requirements in the requirements.txt file.

Getting started

Python Prerequisites

Install python packages with:

  • pip
$ pip install -r requirements.txt

Discord developper configuration

  1. Create an application on Discord Developpers

  2. Enable the bot status in Discord Developpers/applications/{YOUR_APP_ID}/bot

  3. Please make sure you have enabled each needed Privileged Gateway Intents in Discord Developpers/applications/{YOUR_APP_ID}/bot #Privileged Gateway Intents for your application.

  4. Copy the token bot from Discord Developpers/applications/{YOUR_APP_ID}/bot #Token

Tip

In URL replace {YOUR_APP_ID} with your own app/bot ID.

Configure the bot

  1. Paste your discord bot token in the "token" field inside /config/bot.json.

  2. Configure the prefix in the /config/bot.json.

  3. If you are using a database, fill your database credentials in the /config/database.json file.

  4. Inside your SQL database, create the following tables listed in the SQL tables structure section.

Important

If you are NOT using any/or a compatible database, check the Acknowledgement section.

Run the bot

Now that you've set up the Python environment and configured the Discord application, it's time to run your bot.

Open a terminal and navigate to the project directory. Execute the following command:

python bot.py

This will start your Discord bot, and if everything is configured correctly, you should see the bot coming online in your Discord server.

Note

Keep the terminal open while the bot is running. If you encounter any issues, check the logs for error messages (by default discord.log), and ensure that you've followed all the configuration steps accurately.

Congratulations! Your bot is now up and running, ready to respond to commands and interact with users on your Discord server.

Database

Acknowledgement

Important

If you have not planned to use a SQL database:

  1. set the "use_database" field to false in the /config/database.json file.
  2. in the folder /cogs you should remove the following files (which are using the database): birthday.py, croissants.py, invite.py, me.py, metrics.py, starboard.py.

To set up a SQL database such as MariaDB or any other SQL database, and host it on a Raspberry Pi or any other server, you need to follow these steps:

  1. Install MariaDB or any other SQL database on the desired server. The installation process may vary depending on the operating system and which SQL database you have selected. You may also want to install a graphical user interface for your database, such as phpMyAdmin, which makes it easier to manage and configure your database.

  2. Create a new user with password that the bot is going to use and grant the necessary permissions such as SELECT, INSERT, UPDATE, DELETE, and SHOW DATABASES.

  3. If the database is on the same server, no additional configuration is usually required. However, if the database is hosted on a different server, you may need to configure network settings to allow access to the database server. Specifically, you might need to open port 3306, which is the default port for SQL databases, on the server where the database is hosted.

  4. Create a new database. Add the tables listed in the SQL tables structure section. You can change the structure of the tables as you wish, but you will need to reconfigure some keys/values of the /config/cogs.json.

  5. Fill the database settings for your bot in the /config/database.json file as following:

    • use_database: This line configures the bot to either use the database or not. If set to false you won't use any database features and your bot will run.
    • host: Sepcify the IP address/hostname of the database server. It could be a local IP adress if you're running your bot in the same local network than you're database is running (e.g. 192.168.1.31).
    • port: This specifies the port number on which the database server is listening. It's often set to the default SQL port, which is 3306, except if you change it you may not need to change the port number.
    • user: Here, you need to replace "user" with the actual username you will be using to connect to the database server. This should be the username that has appropriate privileges to access the desired database.
    • password: Replace this with the actual password for the specified username. It is the password that allows you to connect to the database server.
    • database: Replace this with the name of the database you want your bot to connect to. Specify the actual name of the database that contains the data your bot needs to access or modify.

SQL tables structure

Note

These tables are required in the database if you have planned to use the bot as if provided

  • table_birthday
CREATE TABLE IF NOT EXISTS `table_birthday`
(
    `guild_id`          BIGINT unsigned NOT NULL,
    `user_id`           BIGINT unsigned NOT NULL,
    `user_birth`        DATE NOT NULL,
CONSTRAINT `me_per_guild` UNIQUE (`guild_id`, `user_id`)
)
ENGINE = InnoDB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_unicode_ci;
  • table_croissants
CREATE TABLE IF NOT EXISTS `table_croissants`
(
    `user_id`           BIGINT unsigned NOT NULL,
    `user_count`        SMALLINT unsigned,
UNIQUE(`user_id`)
)
ENGINE = InnoDB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_unicode_ci;
  • table_invite
CREATE TABLE IF NOT EXISTS `table_invite`
(
    `guild_id`           BIGINT unsigned NOT NULL,
    `channel_id`         BIGINT unsigned NOT NULL,
    `custom_message`     varchar(4096),
UNIQUE(`guild_id`)
)
ENGINE = InnoDB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_unicode_ci;
  • table_me
CREATE TABLE IF NOT EXISTS `table_me`
(
    `guild_id`          BIGINT unsigned NOT NULL,
    `user_id`           BIGINT unsigned NOT NULL,
    `user_me`           varchar(1024),
CONSTRAINT `me_per_guild` UNIQUE (`guild_id`, `user_id`)
)
ENGINE = InnoDB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_unicode_ci;
  • table_metrics
CREATE TABLE IF NOT EXISTS `table_metrics`
(
    `command_name`      varchar(32) NOT NULL,
    `command_count`     MEDIUMINT unsigned NOT NULL,
    `command_type`      varchar(64) NOT NULL,
UNIQUE(`command_name`)
)
ENGINE = InnoDB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_unicode_ci;
  • table_prefix
CREATE TABLE IF NOT EXISTS `table_prefix`
(
    `guild_id`           BIGINT unsigned NOT NULL,
    `guild_prefix`       varchar(256),
UNIQUE(`guild_id`)
)
ENGINE = InnoDB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_unicode_ci;
  • table_starboard
CREATE TABLE IF NOT EXISTS `table_starboard`
(
    `reference_message`   VARCHAR(100) NOT NULL,
    `display_message`     VARCHAR(100) NOT NULL,
    `star_count`          SMALLINT unsigned NOT NULL,
UNIQUE(`reference_message`)
)
ENGINE = InnoDB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_unicode_ci;

Development

To add a new cog, place the Python file in the /cog folder.
While the bot is running, you can dynamically register the cog using the loadcog command followed by the name of the file without the .py extension. If you make changes to the cog after registering it, simply use rl or rel <cog_name> to reload the cog without restarting the bot.

The following commands provide flexibility and efficiency during the development phase, allowing you to seamlessly update and test your bot without restarting it.

Commands Overview:

Command Alias Description Example
?loadcog <cog_name> Loads a cog from the /cogs directory. ?loadcog basic
?unloadcog <cog_name> Unloads a cog from the /cogs directory. ?unloadcog basic
?reloadallcogs rell Reloads all cogs inside the /cogs directory. ?reloadallcogs
?reload <cog1> <cog2> ... rel Reloads specified cogs from the /cogs directory. ?reload basic birthday
?reloadlatest <n_cogs> rl Reloads the n latest edited cogs in the /cogs directory. ?reloadlatest 3
?reloadviews rv Reloads all registered views in the /views directory. ?reloadviews
?reloadconfig rc Reloads all JSON config files inside the /config folder. ?reloadconfig
?synctree <guild_id> st Syncs applications commands with discord. ?synctree or ?synctree 123456789012345678

Most of the time you will be using, rl for reloading the latest edited cogs and rv for reloading all registered views.
These commands are essential for development, often used to quickly apply and test code changes, making the development process smooth and efficient.

Workflows

Update and restart discord bot

Github setup:

  • On Github.com go on your project repository
  • Then click on Settings > Actions > Runners > New self-hosted runner.
  • Then select the right runner-image related to your machine and the right architecture.
  • Then follow the Download and the Configure instructions.

Server setup:

  • If you want to start the self-runner on boot, you can follow this guide. :warning: The self-hosted runner should have the following permissions, install apps and start/restart services. (install the service as --user usernameWithPermissions)

Discord bot service: This step is made for linux only.

  • Create a service file in /etc/systemd/system/your-service-name.service with the following content:
[Unit]
Description=Discord bot startup service
After=multi-user.target

[Service]
Type=simple
Restart=no
User={usernameWithPermissions}
WorkingDirectory=/home/{username}/actions-runner/_work/Discord-Bot/Discord-Bot
ExecStart=python3 /home/{username}/actions-runner/_work/Discord-Bot/Discord-Bot/bot.py

[Install]
WantedBy=multi-user.target

Tip

Replace {username} & {usernameWithPermissions} with your username and Discord-Bot/Discord-Bot with your project name.

  • Then enable the service with systemctl enable your-service-name.service
Contributors :

discord-bot's People

Contributors

dependabot[bot] avatar leo-chartier avatar maxbernard3 avatar paulmarisoumary avatar romainnicolaon avatar theodct avatar vibesxyz avatar warriormachine avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

discord-bot's Issues

aiomysql: RuntimeError

Describe the bug

Can't process 2 query at the same time.

To Reproduce

Steps to reproduce the behavior:

@commands.Cog.listener("on_interaction")
async def on_interaction(self, interaction: discord.Interaction) -> None:
	await self.bot.database.increment(*args)

AND

@app_command.command(name="command", description="Debug command.")
async def command(self, interaction: discord.Interaction) -> None:
	response = await self.bot.database.lookup(*args)
  1. Add these lines of code in a Cog
  2. Run the /command on discord

You can reproduce this error without the code provided, processing 2 query at the same time will raise the error.

Expected behavior

Should not raise the error.

Actual behavior

Summarized error:

RuntimeError: readexactly() called while another coroutine is already waiting for incoming data

Full error:

Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\client.py", line 375, in _run_event
    await coro(*args, **kwargs)
  File "c:\Users\user\Desktop\Discord-Bot\cogs\metrics.py", line 37, in on_interaction
    await self.add_metrics(interaction.command.qualified_name, discord.InteractionType.application_command)
  File "c:\Users\user\Desktop\Discord-Bot\cogs\metrics.py", line 44, in add_metrics
    await self.bot.database.insert(table=self.metrics_data["table"], args={"command_name": command_name, "command_count": 1, "command_type": str(command_type)})
  File "c:\Users\user\Desktop\Discord-Bot\classes\database.py", line 69, in insert
    return await self.query(query)
  File "c:\Users\user\Desktop\Discord-Bot\classes\database.py", line 36, in query
    raise e
  File "c:\Users\user\Desktop\Discord-Bot\classes\database.py", line 25, in query
    await cursor.execute(query)
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages\aiomysql\cursors.py", line 239, in execute
    await self._query(query)
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages\aiomysql\cursors.py", line 457, in _query
    await conn.query(q)
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages\aiomysql\connection.py", line 469, in query
    await self._read_query_result(unbuffered=unbuffered)
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages\aiomysql\connection.py", line 672, in _read_query_result
    await result.read()
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages\aiomysql\connection.py", line 1153, in read
    first_packet = await self.connection._read_packet()
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages\aiomysql\connection.py", line 598, in _read_packet
    packet_header = await self._read_bytes(4)
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages\aiomysql\connection.py", line 646, in _read_bytes
    data = await self._reader.readexactly(num_bytes)
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\asyncio\streams.py", line 708, in readexactly
    await self._wait_for_data('readexactly')
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\asyncio\streams.py", line 488, in _wait_for_data
    raise RuntimeError( 
RuntimeError: readexactly() called while another coroutine is already waiting for incoming data

Environment

  • Operating System Windows 10
  • Python version python3.10.0
  • Dependencies versions aiomysql == 0.1.1

Additional context

We should use aiomysql.pool instead of aiomysql.connect in classes.database.DataSQL.auth.
Know issue: aio-libs/aiomysql/issues/179

Workflow : `update-runner.yml` | additional steps on `Run scripts`

Is your feature request related to a problem? Please describe.

When the update-runner.yml workflow is running, the bot should restart and update its dependencies.
This feature gives a usefull automation for the maintainer.

Describe the solution you'd like

  • Auto-install requirements.txt:
    • pip3 install -r requirements.txt
  • Auto-restart bot.py with (3 ways to do it):
    • Find the previous bot.py process then kill it. Then run the bot.py.
    • Send a "ping" to the bot.py to shutdown. Then run the bot.py.
    • Create a service (discord-bot.service) then restart this service. (needs privileges)

Additional context

⚠️ Security: Edit the CODEOWNERS and add the requirements.txt & the workflow folder.
⚠️ Security: We should take care of each change introduce in a pull request to avoid malicious code deployed on the server.

Cannot import 'Self' from 'typing' (python3.9)

18.11 11:23:01 [Bot] Traceback (most recent call last):
18.11 11:23:01 [Bot] File "/bot.py", line 4, in
18.11 11:23:01 [Bot] from classes.discordbot import DiscordBot
18.11 11:23:01 [Bot] File "/classes/discordbot.py", line 7, in
18.11 11:23:01 [Bot] from typing import List, Self
18.11 11:23:01 [Bot] ImportError: cannot import name 'Self' from 'typing' (/usr/lib/python3.9/typing.py)

Bug with: cogs.croissants

Subject:

The color of the username displayed (in the cogs.croissants) is invalid.

Reproduction steps:

Attribute a 1st role with a color to a user, then attribute a 2nd role without any colour, the 2nd role should be above the 1st.

Expected result:

The username should has the same color as the 1st role.

Actual result:

The username is black.

Aditional content:

Cause(s):

The top role is not always colored.
https://github.com/PaulMarisOUMary/Algosup-Discord/blob/b1c4087fb2821fa76b401d0c9e56b704d9778857/cogs/croissants.py#L68

How to fix:

name_color = author.color

Rewrite bot.py when 2.0.0 of discord.py is release

Is your feature request related to a problem? Please describe.

After 6 month, the development of discord.py has resumed its course.
Many changes are in progress, the structure is being reworked.
With all these changes the bot.py does not work in adequacy with the latest development version (which explains the choice to remain on the version 45d498c1b76deaf3b394d17ccf56112fa691d160 of discord.py for the moment).

Describe the solution you'd like

The structure being different the bot.py will have some breaking change(s) to be compatible with the 2.0.0 version of discord.py.

[CI/CD] Support for Testing Across Multiple Python Versions

Is your feature request related to a problem? Please describe.

The current GitHub Actions workflow for our project does not include testing across multiple Python versions. This makes it challenging to ensure compatibility with different Python releases and identify potential issues early on.

Describe the solution you'd like

A GitHub Actions workflow that enables testing the code across multiple Python versions. This would involve setting up the workflow to run tests on Python from versions 3.8 to the latest 3.x release.

Handle interactive_timeout MYSQL

Reproduce the error:

  • SQL setup (prerequist):
SET GLOBAL interactive_timeout=5
# Set this to 5 if you don't want to wait during 8hours before the error is thrown
# Default value: 28800

(set the interactive timeout before closing the connection to a low value)

  • Test the error:
  1. Initiate a new connection with the DataSQL class.
  2. Query once again and get the error.

Additional doc:

MYSQL Doc
Stackoverflow

(This is a note for myself, I'll fix the bug soon)

[cogs] Create new Cogs.starboard

Table structure (SQL):

CREATE TABLE IF NOT EXISTS `table_starboard`
(
    `reference_message`   BIGINT unsigned NOT NULL,
    `display_message`     BIGINT unsigned NOT NULL,
    `star_count`          SMALLINT unsigned NOT NULL,
UNIQUE(`reference_message`)
)
ENGINE = InnoDB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_unicode_ci;

Note
The table structure may change.
I was thinking about a jump_url instead of using reference_message's id (with benefit of accessing guild id, channel id and message id at the same time).

Bad transparency mask for croissants cog

Describe the bug

This bug seems to appear when a Discord user with an animated profile picture triggers the croissant cog.

To Reproduce

Steps to reproduce the behavior:

  1. Create a Discord account
  2. Buy Nitro
  3. Set an animated profile picture
  4. Go on a server where the bot is
  5. Send a message that starts with Je paye les croissants

Expected behavior

Get a response similar to this one:
Expected behaviour

Actual behavior

Nothing happens on Discord. Behind the scenes, the bot raises and error:

Mar 15 10:53:37 warn python3[110192]:     await coro(*args, **kwargs)
Mar 15 10:53:37 warn python3[110192]:   File "/home/warrior/actions-runner/_work/Algosup-Discord/Algosup-Discord/cogs/croissants.py", line 33, in on_receive_message
Mar 15 10:53:37 warn python3[110192]:     await self.__send_croissants(message)
Mar 15 10:53:37 warn python3[110192]:   File "/home/warrior/actions-runner/_work/Algosup-Discord/Algosup-Discord/cogs/croissants.py", line 52, in __send_croissants
Mar 15 10:53:37 warn python3[110192]:     file=self.__get_screenshot(message.author, message.content)
Mar 15 10:53:37 warn python3[110192]:   File "/home/warrior/actions-runner/_work/Algosup-Discord/Algosup-Discord/cogs/croissants.py", line 85, in __get_screenshot
Mar 15 10:53:37 warn python3[110192]:     img.paste(pfp, (16, 16), pfp)
Mar 15 10:53:37 warn python3[110192]:   File "/usr/local/lib/python3.9/dist-packages/PIL/Image.py", line 1557, in paste
Mar 15 10:53:37 warn python3[110192]:     self.im.paste(im, box, mask.im)
Mar 15 10:53:37 warn python3[110192]: ValueError: bad transparency mask

Environment

  • Discord (web browser or app)

Re-Implement privatevocal cog

Is your feature request related to a problem? Please describe.

The privatevocal cog was a cool feature released in the v1.0. However due to the way it was made, it was very expensive in term of resources, the workload increased over time making the other bot's commands unusable (or with a really hight timeout) which was a big issue. So this cog was deleted on the next release.
I'd like to re-introduce this useful feature with the solution bellow.

Describe the solution you'd like

Replacing the loop_if_connected task with the on_voice_state_update event listener (doc here), with this structure the cog should be way much lighter.
https://github.com/PaulMarisOUMary/Algosup-Discord/blob/1f661b212cc6938f2cc687fa83847ad626fbcc5e/cogs/privatevocal.py#L21-L68

Additional context

Processor usage Before/After disabling the privatevocal cog (released with the v1.0).
Screenshot 2021-09-27 at 09 44 32
(Bot hosted on the cheapest virtual machine on GoogleCloudPlatform.)

Extend cogs.me feature, allow a user to have a /me per guild

Allow each user to have a unique description (/me) per guild.

Introducing new table structure.

CREATE TABLE IF NOT EXISTS `table_me`
(
    `guild_id`          BIGINT unsigned NOT NULL,
    `user_id`           BIGINT unsigned NOT NULL,
    `user_me`           varchar(1024),
CONSTRAINT `me_per_guild` UNIQUE (`guild_id`, `user_id`)
)
ENGINE = InnoDB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_unicode_ci;

Refactor cogs.me(cogs) & table_me(database).

[bug] Task daily_birthday in cogs.birthday doesn't work as expected

Describe the bug

The birthday message is not sent when birthdate reached.

To Reproduce

@tasks.loop(hours=1)
async def daily_birthday(self):
if datetime.now().hour == 9:
guild = get(self.bot.guilds, id=self.subconfig_data["guild_id"])
channel = get(guild.channels, id=self.subconfig_data["channel_id"])
response = await self.bot.database.select(self.subconfig_data["table"], "*")
for data in response:
user_id, user_birth = data
if user_birth.month == datetime.now().month and user_birth.day == datetime.now().day:
timestamp = round(time.mktime(user_birth.timetuple()))
message = f"Remember this date because it's <@{user_id}>'s birthday !\nHe was born <t:{timestamp}:R> !"
images = [
"https://sayingimages.com/wp-content/uploads/funny-birthday-and-believe-me-memes.jpg",
"https://i.kym-cdn.com/photos/images/newsfeed/001/988/649/1e8.jpg",
"https://winkgo.com/wp-content/uploads/2018/08/101-Best-Happy-Birthday-Memes-01-720x720.jpg",
"https://www.the-best-wishes.com/wp-content/uploads/2022/01/success-kid-cute-birthday-meme-for-her.jpg"
]
embed = discord.Embed(title="🎉 Happy birthday !", description=message, colour=discord.Colour.dark_gold())
embed.set_image(url=images[random.randint(0, len(images)-1)])
await channel.send(embed=embed)

Expected behavior

The birthday message should be sent when birthdate reached.

Actual behavior

The birthday message is not sent when birthdate reached.

Screenshots

None

Environment

  • Operating System Debian GNU/Linux 11 (bullseye) aarch64
  • Python version Python3.9.2
  • Dependencies versions: requirement.txt

Additional context

Seems to be an issue related to the algorithm itself.

Bug in traductor

Describe the bug

The traductor translate the wrong message / is triggered when it shouldn't.

To Reproduce

Steps to reproduce the behavior:

  1. Send one message then a second one that trigger the traductor
  2. React with 🔀 on the first one
  3. See that it translated the second one

Expected behavior

Nothing is supposed to happen.

Actual behavior

It translates the wrong message.

Environment

  • Discord

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.