Giter Club home page Giter Club logo

mailslurper's Introduction

mailslurper

MailSlurper

MailSlurper is a small SMTP mail server that slurps mail into oblivion! MailSlurper is perfect for individual developers or small teams writing mail-enabled applications that wish to test email functionality without the risk or hassle of installing and configuring a full blown email server. It's simple to use! Simply setup MailSlurper, configure your code and/or application server to send mail through the address where MailSlurper is running, and start sending emails! MailSlurper will capture those emails into a database for you to view at your leisure.

Compiling

The following are general instructions for compiling MailSlurper. Your details may vary a bit here and there. The below example is based on a Unix-style system, such as Ubuntu or OSX. Furthermore for instructional purposes it is assumed that your GOPATH is set to ~/code/go, and that you have a folder in your source directory called github.com. Your setup may vary. The instructions below also assume you have the following already installed.

  • Go 1.10 (or higher)
  • Git
$ cd ~/code/go/src/github.com
$ mkdir mailslurper
$ cd mailslurper
$ git clone https://github.com/mailslurper/mailslurper.git
$ go get github.com/mjibson/esc
$ cd mailslurper/cmd/mailslurper
$ go get
$ go generate
$ go build

Quickstart With Docker

# Build container image (adjust repo location as necessary)
docker build -t mailslurper 'https://github.com/mailslurper/mailslurper#master'
# Run a temporary container. Note that upon shutdown, all stored messages will be lost when using this config.
docker run -it --rm --name mailslurper -p 8080:8080 -p 8085:8085 -p 2500:2500 mailslurper

Library and Framework Credits

This application uses a lot of great open source libraries.

Themes by Thomas Park at Bootswatch.

License

The MIT License (MIT)

Copyright (c) 2013-2018 Adam Presley

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

mailslurper's People

Contributors

adampresley avatar ajanthan avatar caseywebb avatar christoph-heiss avatar eamirgh avatar erguotou520 avatar keydon avatar mbali avatar mheers avatar parrotmac avatar reallinfo avatar salvorapi avatar thelonelyghost 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  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

mailslurper's Issues

Add ability to sort emails

Add ability to sort emails by click on headers. Sort ascending and descending by the following:

  • Date
  • Subject
  • From

Encrypt config file

The configuration file contains sensitive information. I'd like to encrypt the file for security reasons. Need to consider where to store the key, protect access to it, and so on. Perhaps build a setup process where a key can be provided, then stored in the data store of choice.

Email address containing text 'data'

Sending an email to an address that contains "data" sometimes (about 50% of the time) gets a response code 354 End data with <CR><LF>.<CR><LF> as if the data text should follow, instead of a 250 OK code.

An example address would be: [email protected] or [email protected]

This happens in version 1.6 and 1.7.

telnet exchange sending to [email protected]

            220 Welcome to MailSlurper!
250 Hello. How very nice to meet you!
MAIL FROM:<[email protected]>250 Ok
RCPT TO:[email protected] End data with <CR><LF>.<CR><LF>

RFC2822 date formats not supported

According to the RFC the date format can contain

date-time = [ day-of-week "," ] date time

Mailslurper is recording an error parsing the message date
ERROR - Parsing date Tue, 6 Jun 2017 16:48:07 +0100

it is then trying to send the same format to SQL server and getting an error because the format is wrong SQL expects it in one of the unambiguous formats ie
YYYMMDD HH:mm:ss.ssss
would be my preference

I am not sure how this is working for the majority of your users, maybe they are sending emails using the shorter date format which happens to work.

Improve SMTP worker pool

The current worker pool implementation is slightly manual today. Improve a bit by using native Go concurrency types.

Add paging

Need to determine how many items to show, and page the results accordingly

Error parsing SMTP dates

When sending test email into mailslurper from swaks, there is an error logged:

ERROR - Parsing date Sun, 06 Mar 2016 00:06:53 -0800

Despite being written to the database, none of the mail I sent in via swaks is visible in the web interface; I have a feeling an invalid date causes it to be unsearchable. I know the web interface is working, as I can see the mail generated by send-mail-test.py

Bug With Slurping Body With Python multipart/related Content-Type

When sending mail from Python with multipart/related Content-Type, the body will fail to be slurped due to an issue with the way the content is rendered from Python (using standard libraries). Below is the error message encountered and attached is a Python file to reproduce the issue.

Reproducing Python Script:
python_mail.zip

Error Log:

2016/02/20 10:17:11 libmailslurper: INFO - Mail Date:  Sat, 20 Feb 2016 10:17:10 -0600
2016/02/20 10:17:11 libmailslurper: ERROR - Expected attachment to contain a header section and a body section
2016/02/20 10:17:11 libmailslurper: INFO - Attachment Content-Type:  multipart/alternative; boundary="===============1475100378=="
2016/02/20 10:17:11 libmailslurper: INFO - Attachment MIME-Version:  1.0
2016/02/20 10:17:11 libmailslurper: INFO - Closing connection

Moved from libmailslurper project. Originally entered by @turnkey-commerce

mailslurper tries to remove configured SQLite database

mailslurper exits immediately with this output:

2016/03/05 23:20:15 MailSlurper: INFO - Starting MailSlurper Server v1.8
2016/03/05 23:20:15 libmailslurper: INFO - Connecting to database
2016/03/05 23:20:15 INFO - Creating tables...
2016/03/05 23:20:15 MailSlurper: ERROR - There was an error connecting to your data storage: remove ./mailslurper.db: no such file or directory

It will start if I first touch ./mailslurper.db

Mac app cannot find config.json even though it is present

Downloaded v1.7, put folder in Applications folder, ran mailslurper app, got the following error in terminal:

2015/10/31 19:10:32 MailSlurper: INFO - Starting MailSlurper Server v1.0.0
2015/10/31 19:10:32 MailSlurper: ERROR - There was an error reading your configuration file: open config.json: no such file or directory

As you can see, the json file exists and seems to be configured as per the instructions.
screen shot 2015-10-31 at 19 16 54

Thanks!

Writes into SQLLite database but does not show any emails on web frontend

I configure mailslurper like this:

"wwwAddress": "localhost",
"wwwPort": 8025,
"serviceAddress": "localhost",
"servicePort": 8085,
"smtpAddress": "localhost",
"smtpPort": 2525,
"dbEngine": "SQLite",
"dbHost": "",
"dbPort": 0,
"dbDatabase": "/mailslurper.db",
"dbUserName": "",
"dbPassword": "",
"maxWorkers": 1000,
"autoStartBrowser": false,
"keyFile": "",
"certFile": ""

While testing it prints the following log output:

MailSlurper: INFO - 2017/02/15 10:05:40 libmailslurper: INFO - Mail item 0a1c3ed4-547e-478d-4888-672782fa1a2f written

The Web Frontend does not display any email. When refreshing the mail list it logs only the following:

MailSlurper: INFO - 2017/02/15 10:13:38 MailSlurper: INFO - GET - / (328.855µs)
MailSlurper: INFO - 2017/02/15 10:13:38 Mail collection page 1 retrieved
MailSlurper: INFO - 2017/02/15 10:13:38 GET - /mail?pageNumber=1&message=&start=2017-02-01&end=2017-02-28&orderby=date&dir=desc&_=1487150018285 (526.549µs)

Web interface does not function on case sensitive file systems

It appears that the files in www/assets/mailslurper/js/services are accessed in an inconsistent manner:

$ git grep "services/.lertService"
www/assets/mailslurper/js/controllers/AdminController.js:               "services/alertService",
www/assets/mailslurper/js/controllers/HomeController.js:                "services/alertService",
www/assets/mailslurper/js/controllers/ManageSavedSearchesController.js:         "services/AlertService",
www/assets/mailslurper/js/services/SettingsService.js:          "services/AlertService"

(same goes for MailService)

This causes mailslurper to present a mostly blank web interface when running on Linux.

Unable to parse certain dates

When MailSlurper is handed a date in the header with the format of 30 Nov 2015 13:00:00 -0600 it fails to parse correctly.

Parsing partial attachment panics fatally

Panics with error panic: Expected attachment to contain a header section and a body section.
when a client disconnects before completing a send.

The simplest way to reproduce is to run the example in gopkg.in/gomail.v2 and attaching a file that does not exist( the library panics after the send starts and disconnects before completing the send).

I do realize that the incoming email is part of the problem, but it would be nice to use this application in an environment where email messages are hostile.

Error running on remote host

To reproduce: setup mailslurper on a vagrant. In my example below, I am using Ubuntu 14.04 and the vagrant will have the IP 192.168.33.10.

On the vagrant download and extract mailslurper 1.11.
Modify config to look like the following:

{
        "wwwAddress": "192.168.33.10",
        "wwwPort": 8080,
        "serviceAddress": "192.168.33.10",
        "servicePort": 8085,
        "smtpAddress": "192.168.33.10",
        "smtpPort": 2500,
        "dbEngine": "SQLite",
        "dbHost": "",
        "dbPort": 0,
        "dbDatabase": "./mailslurper.db",
        "dbUserName": "",
        "dbPassword": "",
        "maxWorkers": 1000,
        "autoStartBrowser": false,
        "keyFile": "",
        "certFile": ""
}

Now open up a browser and go to http://192.168.33.10:8080
Mailslurper should appear and you should be greeted with the alert: "There was an error getting mail items". If you check the network requests, you'll notice that there is a request for: "http://0.0.0.0:8085/mail?pageNumber=1&message=&start=2016-03-01&end=2016-03-31&orderby=date&dir=desc&_=1459175709827". Which should not be pointing at 0.0.0.0.

I think this is some sort of timing issue, because a request to http://192.168.33.10:8080/servicesettings returns the expected json:

{
    "serviceAddress": "192.168.33.10",
    "servicePort": ​8085,
    "version": "v1"
}

Receive Mail - Connection timeout. Terminating client connection

Greetings,
I can see the email hitting MailSlurper, but the final step states Connection timeout. Terminating client connection.

image

I'm not entirely sure how to debug this, I haven't been able to find any logs.

My config:
{
"wwwAddress": "local.mailslurper",
"wwwPort": 8585,
"serviceAddress": "local.mailslurper",
"servicePort": 8085,
"smtpAddress": "local.mailslurper",
"smtpPort": 2525,
"dbEngine": "MSSQL",
"dbHost": "momentumsql.momentum.com",
"dbPort": 1433,
"dbDatabase": "mailslurper",
"dbUserName": "SqlUsername",
"dbPassword": "SqlPassword",
"maxWorkers": 1000,
"autoStartBrowser": false,
"keyFile": "",
"certFile": ""
}

Nothing gets written to the database and with every subsequent test it grows the queue.
What is exactly timing out and how can I resolve it?

http://local.mailslurper:8585/ returns client interface
http://local.mailslurper:8085/ returns 404 page not found

Any and all help is appreciated.

Thank you kindly,
Adam

Crash on sigquit

Crashes when I try to stop it with kill -3 PID. Repeatable error (every time).

SIGQUIT: quit
PC=0x468733 m=2

goroutine 0 [idle]:
runtime.futex(0x1597b90, 0x0, 0x7fcbc5940db8, 0x0, 0x0, 0x46855c, 0x3c, 0x0, 0x41937b, 0x1597b90, ...)
/usr/local/go/src/runtime/sys_linux_amd64.s:303 +0x23
runtime.futexsleep(0x1597b90, 0x0, 0xdf8475800)
/usr/local/go/src/runtime/os1_linux.go:57 +0xf0
runtime.notetsleep_internal(0x1597b90, 0xdf8475800, 0xc820000900)
/usr/local/go/src/runtime/lock_futex.go:174 +0x12b
runtime.notetsleep(0x1597b90, 0xdf8475800, 0x266962251e217)
/usr/local/go/src/runtime/lock_futex.go:194 +0x6b
runtime.sysmon()
/usr/local/go/src/runtime/proc.go:3477 +0x487
runtime.mstart1()
/usr/local/go/src/runtime/proc.go:1095 +0xec
runtime.mstart()
/usr/local/go/src/runtime/proc.go:1065 +0x72

goroutine 1 [IO wait]:
net.runtime_pollWait(0x7fcbc62866f0, 0x72, 0x0)
/usr/local/go/src/runtime/netpoll.go:160 +0x60
net.(_pollDesc).Wait(0xc82036e7d0, 0x72, 0x0, 0x0)
/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(_pollDesc).WaitRead(0xc82036e7d0, 0x0, 0x0)
/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(_netFD).accept(0xc82036e770, 0x0, 0x7fcbc6240800, 0xc8204a3de0)
/usr/local/go/src/net/fd_unix.go:426 +0x27c
net.(_TCPListener).AcceptTCP(0xc8204ae000, 0x0, 0x0, 0x0)
/usr/local/go/src/net/tcpsock_posix.go:254 +0x4d
net/http.tcpKeepAliveListener.Accept(0xc8204ae000, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/net/http/server.go:2427 +0x41
crypto/tls.(_listener).Accept(0xc8204a3dc0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/crypto/tls/tls.go:52 +0x60
net/http.(_Server).Serve(0xc82008d500, 0x7fcbc6286870, 0xc8204a3dc0, 0x0, 0x0)
/usr/local/go/src/net/http/server.go:2117 +0x129
net/http.(_Server).ListenAndServeTLS(0xc82008d500, 0xc82037d340, 0x1e, 0xc82037d320, 0x1d, 0x0, 0x0)
/usr/local/go/src/net/http/server.go:2278 +0x39a
github.com/mailslurper/libmailslurper/server.startListener(0xc82008d500, 0xc82037d340, 0x1e, 0xc82037d320, 0x1d, 0xc82034cc90, 0xc82049ebd0, 0x9, 0x1f5a, 0x0, ...)
/code/go/src/github.com/mailslurper/libmailslurper/server/HTTPListenerService.go:108 +0x1ee
github.com/mailslurper/libmailslurper/server.(_HTTPListenerService).StartHTTPListener(0xc8204c5c88, 0x0, 0x0)
/code/go/src/github.com/mailslurper/libmailslurper/server/HTTPListenerService.go:102 +0x347
github.com/mailslurper/libmailslurper.StartServiceTier(0xc8204c5ed8, 0x0, 0x0)
/code/go/src/github.com/mailslurper/libmailslurper/ServiceTier.go:29 +0x350
main.main()
/code/go/src/github.com/mailslurper/mailslurper/mailslurper.go:125 +0xb77

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1998 +0x1

goroutine 5 [syscall]:
os/signal.signal_recv(0x0)
/usr/local/go/src/runtime/sigqueue.go:116 +0x132
os/signal.loop()
/usr/local/go/src/os/signal/signal_unix.go:22 +0x18
created by os/signal.init.1
/usr/local/go/src/os/signal/signal_unix.go:28 +0x37

goroutine 18 [select, locked to thread]:
runtime.gopark(0xb79500, 0xc820181728, 0xa72ac8, 0x6, 0x18, 0x2)
/usr/local/go/src/runtime/proc.go:262 +0x163
runtime.selectgoImpl(0xc820181728, 0x0, 0x18)
/usr/local/go/src/runtime/select.go:392 +0xa67
runtime.selectgo(0xc820181728)
/usr/local/go/src/runtime/select.go:215 +0x12
runtime.ensureSigM.func1()
/usr/local/go/src/runtime/signal1_unix.go:279 +0x358
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1998 +0x1

goroutine 19 [chan receive]:
github.com/adampresley/sigint.ListenForSIGINT.func1(0xc820062180, 0xb78d48)
/code/go/src/github.com/adampresley/sigint/sigint.go:49 +0x43
created by github.com/adampresley/sigint.ListenForSIGINT
/code/go/src/github.com/adampresley/sigint/sigint.go:53 +0xdd

goroutine 20 [chan receive]:
database/sql.(*DB).connectionOpener(0xc8204169a0)
/usr/local/go/src/database/sql/sql.go:727 +0x45
created by database/sql.Open
/usr/local/go/src/database/sql/sql.go:493 +0x33f

goroutine 21 [IO wait]:
net.runtime_pollWait(0x7fcbc62867b0, 0x72, 0x0)
/usr/local/go/src/runtime/netpoll.go:160 +0x60
net.(_pollDesc).Wait(0xc82034e060, 0x72, 0x0, 0x0)
/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(_pollDesc).WaitRead(0xc82034e060, 0x0, 0x0)
/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(_netFD).accept(0xc82034e000, 0x0, 0x7fcbc6240800, 0xc820324000)
/usr/local/go/src/net/fd_unix.go:426 +0x27c
net.(_TCPListener).AcceptTCP(0xc8204920e0, 0x41ae29, 0x0, 0x0)
/usr/local/go/src/net/tcpsock_posix.go:254 +0x4d
net.(_TCPListener).Accept(0xc8204920e0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/net/tcpsock_posix.go:264 +0x3d
crypto/tls.(_listener).Accept(0xc82034b460, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/crypto/tls/tls.go:52 +0x60
github.com/mailslurper/libmailslurper/server.Dispatch(0xc820062a20, 0x7fcbc6286870, 0xc82034b460, 0xc82048dee0, 0x1, 0x1)
/code/go/src/github.com/mailslurper/libmailslurper/server/SmtpListener.go:90 +0xb5
created by main.main
/code/go/src/github.com/mailslurper/mailslurper/mailslurper.go:86 +0x8ab

goroutine 22 [IO wait]:
net.runtime_pollWait(0x7fcbc6286630, 0x72, 0x0)
/usr/local/go/src/runtime/netpoll.go:160 +0x60
net.(_pollDesc).Wait(0xc82041b950, 0x72, 0x0, 0x0)
/usr/local/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(_pollDesc).WaitRead(0xc82041b950, 0x0, 0x0)
/usr/local/go/src/net/fd_poll_runtime.go:78 +0x36
net.(_netFD).accept(0xc82041b8f0, 0x0, 0x7fcbc6240800, 0xc82034bf60)
/usr/local/go/src/net/fd_unix.go:426 +0x27c
net.(_TCPListener).AcceptTCP(0xc820028000, 0x0, 0x0, 0x0)
/usr/local/go/src/net/tcpsock_posix.go:254 +0x4d
net/http.tcpKeepAliveListener.Accept(0xc820028000, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/net/http/server.go:2427 +0x41
crypto/tls.(_listener).Accept(0xc82034bf40, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/crypto/tls/tls.go:52 +0x60
net/http.(_Server).Serve(0xc820498080, 0x7fcbc6286870, 0xc82034bf40, 0x0, 0x0)
/usr/local/go/src/net/http/server.go:2117 +0x129
net/http.(_Server).ListenAndServeTLS(0xc820498080, 0xc82037d340, 0x1e, 0xc82037d320, 0x1d, 0x0, 0x0)
/usr/local/go/src/net/http/server.go:2278 +0x39a
github.com/mailslurper/mailslurper/services/listener.(_HTTPListenerService).StartHTTPListener(0xc820348440, 0xc8201820e0, 0x0, 0x0)
/code/go/src/github.com/mailslurper/mailslurper/services/listener/HTTPListenerService.go:148 +0x499
main.main.func2(0xc820348440, 0xc8201820e0)
/code/go/src/github.com/mailslurper/mailslurper/mailslurper.go:104 +0x38
created by main.main
/code/go/src/github.com/mailslurper/mailslurper/mailslurper.go:108 +0xaa9

goroutine 34 [chan receive]:
github.com/mailslurper/libmailslurper/server.Dispatch.func1(0xc82048dee0, 0x1, 0x1, 0xc82035a000)
/code/go/src/github.com/mailslurper/libmailslurper/server/SmtpListener.go:78 +0x258
created by github.com/mailslurper/libmailslurper/server.Dispatch
/code/go/src/github.com/mailslurper/libmailslurper/server/SmtpListener.go:84 +0x9b

rax 0xfffffffffffffffc
rbx 0x7fcbc5940db8
rcx 0x468733
rdx 0x0
rdi 0x1597b90
rsi 0x0
rbp 0x0
rsp 0x7fcbc5940d80
r8 0x0
r9 0x0
r10 0x7fcbc5940db8
r11 0x246
r12 0x0
r13 0x0
r14 0x7fcbc59419c0
r15 0x7fcbc5941700
rip 0x468733
rflags 0x246
cs 0x33
fs 0x0
gs 0x0

DB Connection errors do not report correctly

When MailSlurper has a problem connecting to a 3rd party database engine (MySQL, MSSQL), the interface does not report a friendly error. Instead a popup notification with the text object - object is displayed. This popup should instead show a friendly error message.

Implement timeout for ServerPool

When there are no workers available the listener blocks. This means a client connected will be blocked as well. Consider implementing a timeout when no workers are available.

Weird encoding issue

Some mails are coming in with odd encoding with stuff like src=3d"http://..."

No DATA section causes panic

Currently the library is set to panic when there is no DATA section found. Come up with a better way to report this problem and no issue a panic.

Moved over from libmailslurper

Auto-refresh

Build ability to specify an auto-refresh timer. This will be setup via settings, and offer the following intervals:

  • Every minute
  • Every 5 minutes
  • Every 10 minutes

Version check in admin

Add the ability for MailSlurper to lookup the current version information from the master branch in Github and display an alert box on the admin screen if the version of MailSlurper being run is behind.

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.