Giter Club home page Giter Club logo

telegramircd's Introduction

简体中文

telegramircd IRC Telegram Gitter

telegramircd is an IRC server that enables IRC clients to send and receive messages from Telegram.

telegramircd uses telethon-sync to communicate with Telegram servers.

Installation

  • git clone https://github.com/MaskRay/telegramircd && cd telegramircd
  • python >= 3.5
  • libmagic
  • pip3 install -r requirements.txt

Create a Telegram App.

  • Visit https://my.telegram.org/apps, create an App, and get app_id, app_hash.
  • Update config: change tg-api-id, tg-api-hash, tg-phone; change tg-session-dir to the directory where you want to store telegramircd.session (defaults to . for current working directory, it will be created after the initial login)
  • ./telegramircd.py -c config

Arch Linux

The git clone and pip3 install -r requirements.txt steps can be replaced with:

  • Install aur/telegramircd-git (which depends on aur/python-telethon. You may also use archlinuxcn/python-telethon).
  • The server is installed at /usr/bin/telegramircd.

A systemd service template is install at /lib/systemd/system/telegramircd.service. You may create /etc/systemd/system/telegramircd.service from the template. Change the User= and Group= fields to whom telethon is installed with. Run systemctl start telegramircd.

Running telegramircd

telegramircd.py (the server) will listen on 127.0.0.1:6669 (IRC, irc-listen, irc-port) and 127.0.0.1:9003 (HTTPS + WebSocket over TLS, http-url).

Connect to the IRC server with you favorite IRC client. You will join the channel +telegram automatically. For the first login, you need to type /oper a $login_code where $login_code is sent to your phone as a short message. If two-step verification is enabled, you will need to type /oper a $password. A file named $tg_session.session is saved in $tg_session_dir, and login code is not required for future logins.

Session files can also be created by executing TelegramClient(session_name, api_id, api_hash) (see https://github.com/LonamiWebs/Telethon).

If you run the server on another machine, it is recommended to set up IRC over TLS and an IRC connection password with a few more options: --irc-cert /path/to/irc.key --irc-key /path/to/irc.cert --irc-password yourpassword. As an alternative to the IRC connection password, you may specify --sasl-password yourpassword and authenticate with SASL PLAIN. You can reuse the HTTPS certificate+key. If you use WeeChat and find it difficult to set up a valid certificate (gnutls checks the hostname), type the following lines in WeeChat:

/set irc.server.telegram.ssl on
/set irc.server.telegram.ssl_verify off
/set irc.server.telegram.password yourpassword

Serve file links via HTTPS

A few more options: --http-key /etc/telegramircd/key.pem --http-cert /etc/telegramircd/cert.pem --http-url https://127.1:9003. File links will be shown as https://127.1:9003/document/$id.

You may create a CA certificate/key pair and use that to sign another certificate/key pair.

openssl req -x509 -newkey rsa:2048 -nodes -keyout ca.key.pem -out ca.cert.pem -days 9999 -subj '/CN=127.0.0.1'
openssl req -new -newkey rsa:2048 -nodes -keyout key.pem -subj '/CN=127.0.0.1' |
  openssl x509 -req -out cert.pem -CAkey ca.key.pem -CA ca.cert.pem -set_serial 2 -days 9999 -extfile <(
    printf "subjectAltName = IP:127.0.0.1, DNS:localhost")

Chrome/Chromium

  • Visit chrome://settings/certificates, import ca.cert.pem, click the Authorities tab, select the 127.0.0.1 certificate, Edit->Trust this certificate for identifying websites.

The IP address or the domain name should match the subjectAlternativeName fields. Chrome has removed support for commonName matching in certificates since version 58. See https://developers.google.com/web/updates/2017/03/chrome-58-deprecations#remove_support_for_commonname_matching_in_certificates for detail.

Firefox

  • Install extension Redirector, redirects app.js as above, click Applies to: Main window (address bar), Scripts.
  • Visit one file link, Firefox will show "Your connection is not secure", Advanced->Add Exception->Confirm Security Exception.

Usage

  • Run telegramircd.py.
  • Connect to 127.0.0.1:6669 in your IRC client

You will join +telegram channel automatically and find your contact list there. Some commands are available:

  • help
  • status, mutual contact list、group/supergroup list
  • eval $expr: eval the Python expression $expr. Examples:
    eval client.peer_id2special_room
    eval client.peer_id2special_user
    

The server will be bound to one account, however, you may have more than one IRC clients connected to the server.

IRC features

  • Surnames come first when displaying Chinese names for users without username. SpecialUser#name
  • Standard IRC channels have names beginning with #.
  • Telegram channels/chats have names beginning with &. The channel name is generated from the group title. SpecialChannel#update
  • Contacts have modes +v (voice, usually displayed with a prefix +). SpecialChannel#update_detail
  • Multi-line messages: !m line0\nline1
  • Multi-line messages: !html line0<br>line1
  • nick0: nick1: test will be converted to @GroupAlias0 @GroupAlias1 test, where GroupAlias0 is the name set by that user, not your Set Remark and Tag. It corresponds to On-screen names in the mobile application.
  • Reply to the message at 12:34:SS: @1234 !m multi\nline\nreply, which will be sent as 「Re GroupAlias: text」text
  • Reply to the message at 12:34:56: !m @123456 multi\nline\nreply
  • Reply to the penultimate message (your own messages are not counted) in this channel/chat: @2 reply
  • Paste detection. PRIVMSG lines will be hold for up to 0.1 seconds, lines in this interval will be packed to a multiline message

!m , @3 , nick: can be arranged in any order

For WeeChat, its anti-flood mechanism will prevent two user messages sent to IRC server in the same time. Disable anti-flood to enable paste detection.

/set irc.server.wechat.anti_flood_prio_high 0

server-time extension from IRC version 3.1, 3.2. telegramircd.py includes the timestamp (obtained from JavaScript) in messages to tell IRC clients that the message happened at the given time. See http://ircv3.net/irc/. Seehttp://ircv3.net/software/clients.html for Client support of IRCv3.

Configuration for WeeChat:

/set irc.server_default.capabilities "account-notify,away-notify,cap-notify,multi-prefix,server-time,znc.in/server-time-iso,znc.in/self-message"

Supported IRC commands:

  • /cap, supported capabilities.
  • /dcc send $nick/$channel $filename, send image or file。This feature borrows the command /dcc send which is well supported in IRC clients. See https://en.wikipedia.org/wiki/Direct_Client-to-Client#DCC_SEND.
  • /invite $nick [$channel], invite a contact to the channel.
  • /kick $nick, delete a group member. You must be the group leader to do this. Due to the defect of the Web client, you may not receive notifcations about the change of members.
  • /kill $nick [$reason], cause the connection of that client to be closed
  • /list, list groups.
  • /mode +m, no rejoin in --join new mode. /mode -m to revert.
  • /names, update nicks in the channel.
  • /part [$channel], no longer receive messages from the channel. It just borrows the command /part and it will not leave the group.
  • /query $nick, open a chat window with $nick.
  • /topic topic, change the topic of a group. Because IRC does not support renaming of a channel, you will leave the channel with the old name and join a channel with the new name.
  • /who $channel, see the member list.

Server options

  • --config, short option -c, config file path, see config
  • HTTP/WebSocket related options
    • --http-cert cert.pem, TLS certificate for HTTPS. You may concatenate certificate+key, specify a single PEM file and omit --http-key. Use HTTP if neither --http-cert nor --http-key is specified.
    • --http-url http://localhost, Show file links as http://localhost/document/$id .
    • --http-key key.pem, TLS key for HTTPS.
    • --http-listen 127.1 ::1, change HTTPS listen address to 127.1 and ::1, overriding --listen.
    • --http-port 9003, change HTTPS listen port to 9003.
  • Groups that should not join automatically. This feature supplements join mode.
    • --ignore '&fo[o]' '&bar', do not auto join channels whose names(generated from topics) partially match regex &fo[o] or &bar
    • --ignore-topic 'fo[o]' bar, short option -I, do not auto join channels whose topics match regex fo[o] or bar
  • --ignore-bot, ignore private messages with bots
  • IRC related options
    • --irc-cert cert.pem, TLS certificate for IRC over TLS. You may concatenate certificate+key, specify a single PEM file and omit --irc-key. Use plain IRC if neither --irc-cert nor --irc-key is specified.
    • --irc-key key.pem, TLS key for IRC over TLS.
    • --irc-listen 127.1 ::1, change IRC listen address to 127.1 and ::1, overriding --listen.
    • --irc-nicks ray ray1, reverved nicks for clients. SpecialUser will not have these nicks.
    • --irc-password pass, set the connection password to pass.
    • --irc-port 6669, IRC server listen port.
  • Join mode, short option -j
    • --join auto, default: join the channel upon receiving the first message, no rejoin after issuing /part and receiving messages later
    • --join all: join all the channels
    • --join manual: no automatic join
    • --join new: like auto, but rejoin when new messages arrive even if after /part
  • --listen 127.0.0.1, short option -l, change IRC/HTTP/WebSocket listen address to 127.0.0.1.
  • Server side log
    • --logger-ignore '&test0' '&test1', list of ignored regex, do not log contacts/groups whose names match
    • --logger-mask '/tmp/telegram/$channel/%Y-%m-%d.log', format of log filenames
    • --logger-time-format %H:%M, time format of server side log
  • --mark-read, when to mark_read private messages from users
    • always, mark_read all messages
    • reply, default: mark_read when sending messages to the peer
    • never, never
  • --paste-wait, PRIVMSG lines will be hold for up to $paste_wait seconds, lines in this interval will be packed to a multiline message
  • --sasl-password pass, set the SASL password to pass.
  • --special-channel-prefix, choices: &, !, #, ##, prefix for SpecialChannel. Quassel does not seem to support channels with prefixes &, --special-channel-prefix '##' to make Quassel happy
  • Telegram related options
    • --tg-phone, phone number
    • --tg-api-id
    • --tg-api-hash
    • --tg-session telegramircd, session filename.
    • --tg-session-dir ., where to save session file

See telegramircd.service for a template of /etc/systemd/system/telegramircd.service. Change User= and Group=. Change the User= and Group= fields.

Demo

Known issues

  • Sometimes struct.error: required argument is not an integer when calling self.channel_get_participants(channel)

telegramircd's People

Contributors

aconitumnapellus avatar alecdwm avatar maskray avatar rodneyrod avatar stkw0 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

telegramircd's Issues

English translation of README?

I know it might be out of scope for you, but I would be greatly appreciative if there was an English translation of the README file.

Something Error...

你好。
当我运行./telegramircd.py时,报错:

INFO: 127.0.0.1 - - [06/Dec/2016:09:21:22 +0000] "GET /app.js HTTP/1.1" 200 3143478 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36"
INFO: WebSocket client connected from ('127.0.0.1', 60470)
ERROR: Error handling request
Traceback (most recent call last):
File "/home/kin/.local/lib/python3.5/site-packages/aiohttp/server.py", line 265, in start
yield from self.handle_request(message, payload)
File "/home/kin/.local/lib/python3.5/site-packages/aiohttp/web.py", line 96, in handle_request
resp = yield from handler(request)
File "./telegramircd.py", line 66, in handle_web_socket
Server.instance.on_websocket(data)
File "./telegramircd.py", line 1602, in on_websocket
client.on_websocket(data)
File "./telegramircd.py", line 1377, in on_websocket
getattr(SpecialCommands, command)(self, data)
File "./telegramircd.py", line 478, in room
room = client.ensure_special_room(record)
File "./telegramircd.py", line 1134, in ensure_special_room
assert isinstance(record['flags'], int)
KeyError: 'flags'

Stickers not displaying as images

Links show as 'MYSERVERDOMAIN:9003/document/id' but with no file type appended to the end.
In Firefox 57 I get 'The Image can't be displayed because it contains errors', and it tries to parse it as a JPEG.

Webpages display as gibberish

When a received link has Telegram preview, it displays incorrectly and URL is not shown. For example:

[webpage] {'webpage': {'id': 1616137859779238602, 'date': datetime.datetime(2018, 1, 12, 13, 12, 35)}}

Random crash

For some reason it just suddenly died.

e', 'type': 'm', 'location': {'_': 'FileLocation', 'dc_id': 4, 'volume_id': 400187400703, 'local_id': 84341, 'secret': -73309301113771800}, 'w': 320, 'h': 168, 'size': 12482}, {'_': 'PhotoSize', 'type': 'x', 'location': {'_': 'FileLocation', 'dc_id': 4, 'volume_id': 400187400703, 'local_id': 84342, 'secret': -3508359373354518116}, 'w': 800, 'h': 420, 'size': 46335}, {'_': 'PhotoSize', 'type': 'y', 'location': {'_': 'FileLocation', 'dc_id': 4, 'volume_id': 400187400703, 'local_id': 84343, 'secret': -2226223468058160481}, 'w': 1200, 'h': 630, 'size': 68430}], 'has_stickers': False}, 'embed_url': None, 'embed_type': None, 'embed_width': None, 'embed_height': None, 'duration': None, 'author': None, 'document': None, 'cached_page': None}
WARNING: socket.send() raised exception.
WARNING: socket.send() raised exception.
WARNING: socket.send() raised exception.
WARNING: socket.send() raised exception.
WARNING: socket.send() raised exception.
WARNING: socket.send() raised exception.
WARNING: socket.send() raised exception.
WARNING: socket.send() raised exception.

Started to work again by force-killing the process manually with kill <pid> and starting again. python3 --version:
Python 3.6.9. Ubuntu 18.04.5 LTS.

Groups showing up as users, not channels, when first connecting to telegramircd

After updating to the latest build, I'm getting an issue where every time I reset the daemon and connect to it for the first time again, it adds a list of my groups, but it adds them as users instead of channels, and when it starts fetching messages from those groups, it just creates new channels leaving the ones created at the initialisation and it fills up my room list with duplicates.

Traceback error

Traceback (most recent call last):
File "/home/USERNAME/.local/lib/python3.5/site-packages/telethon/update_state.py", line 119, in _worker_loop
handler(update)
File "./telegramircd.py", line 2011, in on_telegram_update
getattr(TelegramUpdate, name)(self, update)
File "./telegramircd.py", line 1666, in UpdateNewChannelMessage
server.on_telegram_update_message(update, update.message)
File "./telegramircd.py", line 2056, in on_telegram_update_message
text = '[{}] {}'.format(type(msg.media).name, msg.media.to_dict())
TypeError: 'str' object is not callable

Setting join: all doesn't do anything.

When I set join: all, it doesn't autojoin to all channels on connect.

The only part of the code referring to this option is lines 1956-1957 where a nonexistent function Server.auto_join() is called. This gives an error.

Traceback (most recent call last):
  File "telegramircd.py", line 313, in init
    await web.channel_list()
  File "telegramircd.py", line 288, in channel_list
    server.ensure_special_room(data)
  File "telegramircd.py", line 1957, in ensure_special_room
    self.auto_join(room)
AttributeError: 'Server' object has no attribute 'auto_join'

So:

  1. These lines probably should be looping over self.auth_clients() and calling client.auto_join for each client.
  2. This should be done after authentication if options.join=='all'. (Currently apparently the user can ensure this function is called by the IRC command /list but that's not what this option is supposed to do.)

Server hangs after receiving image files

After receiving an image file (doesn't seem to happen for gifs), the server will hang with this error:

May 16 19:00:55 vps-c41f521a python3[306830]: Downloading file in chunks of 131072 bytes
May 16 19:00:55 vps-c41f521a python3[306830]: 127.0.0.1 [16/May/2021:19:00:55 +0000] "GET /document/1.jpg HTTP/1.0" 500 207 "-" "Mozilla/5.0 (compatible; The Lounge IRC Client; +https://github.com/thelounge/thelounge) facebookexternalhit/>
May 16 19:01:10 vps-c41f521a python3[306830]: Downloading file in chunks of 131072 bytes
May 16 19:01:10 vps-c41f521a python3[306830]: Unhandled exception while processing TLMessage(msg_id=6962965205144311809, seq_no=95, obj=RpcResult(req_msg_id=6962965204889086836, body=None, error=RpcError(error_code=406, error_message='FIL>
                                              Traceback (most recent call last):
                                                File "/home/telegramircd/.local/lib/python3.8/site-packages/telethon/network/mtprotosender.py", line 486, in _recv_loop
                                                  self._process_message(message)
                                                File "/home/telegramircd/.local/lib/python3.8/site-packages/telethon/network/mtprotosender.py", line 506, in _process_message
                                                  handler(message)
                                                File "/home/telegramircd/.local/lib/python3.8/site-packages/telethon/network/mtprotosender.py", line 528, in _handle_rpc_result
                                                  error = rpc_message_to_error(rpc_result.error)
                                                File "/home/telegramircd/.local/lib/python3.8/site-packages/telethon/errors/__init__.py", line 70, in rpc_message_to_error
                                                  return cls(rpc_error.error_message)
                                                File "/home/telegramircd/.local/lib/python3.8/site-packages/telethon/errors/rpcbaseerrors.py", line 76, in __init__
                                                  super().__init__(message)
                                              TypeError: __init__() missing 1 required positional argument: 'message'

The server still sends out messages from Telegram, but cannot send them if you try to send a message via IRC. The HTTP server also hangs. This does not stop until a restart, making this a very big problem. Any idea what's wrong here? Perhaps a telegram library needs to be upgraded?

Myself is double posting

In my groups, I see two users, [USERNAME] and [USERNAME]1
Whenever I post in a group, on my IRC client it double posts, with my reply being posted by both [USERNAME] and [USERNAME]1.

The double post does not occur in the actual chat room on Telegram, checked with Telegram Web and only one post was showing.

telegramircd crashed intermittently

Below is the dump from the program:

INFO: [IRC NAME]![HOSTNAME]@127.0.0.1 registered
ERROR: Task exception was never retrieved
future: <Task finished coro=<Web.handle_telegram_cli() done, defined at /home/[USERNAME]/git/telegramircd/telegramircd.py:106> exception=AttributeError("'Web' object has no attribute 'message'",)>
Traceback (most recent call last):
File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
result = coro.send(None)
File "/home/[USERNAME]/git/telegramircd/telegramircd.py", line 132, in handle_telegram_cli
Server.instance.on_telegram_cli(data)
File "/home/[USERNAME]/git/telegramircd/telegramircd.py", line 1717, in on_telegram_cli
client.on_telegram_cli(data)
File "/home/[USERNAME]/git/telegramircd/telegramircd.py", line 1515, in on_telegram_cli
getattr(SpecialCommands, name)(self, data)
File "/home/[USERNAME]/git/telegramircd/telegramircd.py", line 595, in message
client.ensure_special_room(data['to']).on_telegram_cli_message(data)
File "/home/[USERNAME]/git/telegramircd/telegramircd.py", line 1143, in on_telegram_cli_message
irc_message(self.client, sender, self.name, self, data)
File "/home/[USERNAME]/git/telegramircd/telegramircd.py", line 291, in irc_message
del web.message[msg['id']]
AttributeError: 'Web' object has no attribute 'message'

Image captions or text in messages containing a URL are not shown

I'm using branch master (commit 5b84bbf9f08032a8ab6517dfa3e9f47fe9f6b28a) of telegramircd and version 0.16.2.2 of telethon (obtained by pip3 install telethon). (Edit: I updated telethon to 0.16.2.3, but the bug remains.)


Whenever someone sends an image with a caption, my IRC client only gets the image url created by telecramid, not the caption. Whenever someone sends a message containing an URL, I only get or the webpage and its title information, not the full message.


Examples:

This is what Telegram web client shows for image with caption: https://i.imgur.com/5telBU6.png

But my IRC client only shows: 13:23:33 <xx> [photo] https://[xx]/document/2.jpg

Telegram web for a message containing a URL: https://i.imgur.com/yQQAV8j.png

IRC: 13:30:18 <xx> [WebPage] https://github.com/MaskRay/telegramircd MaskRay/telegramircd

TGS support?

First of all, thank you for the awesome piece of software! This is perfect for my needs. Was amazed telegramircd to support converting images, stickers and videos to urls, magnificent! Is it possible for telegramircd to support animated stickers (.TGS) as well? Currently they show up as [MessageMediaUnsupported] {'_': 'MessageMediaUnsupported'} whic is not bad, but I'm curious anyway.

Application.make_handler(...) is deprecated, use AppRunner API instead

I am trying to run using python3.8 but I keep running into this

telegramircd.py:135: DeprecationWarning: Application.make_handler(...) is deprecated, use AppRunner API instead self.handler = self.app.make_handler() telegramircd.py:111: RuntimeWarning: coroutine 'TelegramBaseClient.connect' was never awaited self.proc.connect() RuntimeWarning: Enable tracemalloc to get the object allocation traceback Traceback (most recent call last): File "telegramircd.py", line 294, in init web.get_self() File "telegramircd.py", line 290, in get_self server.user_id = data.id AttributeError: 'coroutine' object has no attribute 'id' telegramircd.py:298: RuntimeWarning: coroutine 'UserMethods.get_me' was never awaited traceback.print_exc() RuntimeWarning: Enable tracemalloc to get the object allocation traceback

I've tried older versions of aiohttp but have no luck. Any ideas?

Login failed if the account's 2FA is enabled

Hello.
I found a problem that the program init will be failed if the account's 2FA is enabled.
When entering the login code, the program will be restarted without any notification for entering 2FA password. The error log is there:

Traceback (most recent call last):
  File "telegramircd.py", line 658, in oper
    ok = web.proc.sign_in(options.tg_phone, password)
  File "/lib/python3.5/site-packages/telethon/telegram_client.py", line 435, in sign_in
    result = self(SignInRequest(phone, phone_code_hash, str(code)))
  File "/lib/python3.5/site-packages/telethon/telegram_bare_client.py", line 461, in __call__
    result = self._invoke(call_receive, *requests)
  File "/lib/python3.5/site-packages/telethon/telegram_bare_client.py", line 558, in _invoke
    raise next(x.rpc_error for x in requests if x.rpc_error)
telethon.errors.rpc_error_list.SessionPasswordNeededError: Two-steps verification is enabled and a password is required

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "telegramircd.py", line 1560, in handle_irc
    self.handle_command(command, args)
  File "telegramircd.py", line 1516, in handle_command
    fn(*ba.args)
  File "telegramircd.py", line 661, in oper
    except SessionPasswordNeededError:
NameError: name 'SessionPasswordNeededError' is not defined

Error when running telegramicd.py

When running 'python3 ./telegramircd.py'

File "telegramircd.py", line 57
async def send_command(self, command, timeout=None):
^
SyntaxError: invalid syntax

Installed the dependencies and followed the instructions in the readme and this still occurs, on Ubuntu 14.04.

Not connecting to Telegram

I am running the server like this:
~/telegramircd$ ./telegramircd.py -c config
./telegramircd.py:111: RuntimeWarning: coroutine 'TelegramBaseClient.connect' was never awaited
self.proc.connect()
Traceback (most recent call last):
File "./telegramircd.py", line 294, in init
web.get_self()
File "./telegramircd.py", line 290, in get_self
server.user_id = data.id
AttributeError: 'coroutine' object has no attribute 'id'
./telegramircd.py:298: RuntimeWarning: coroutine 'UserMethods.get_me' was never awaited
traceback.print_exc()
INFO: [email protected] registered

I am able to connect to it via WeeChat and join #telegram, but nothing happens past that. I don't receive the code for oper. Is there any additional logging I could collect to figure out what's wrong?

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.