Browse Source

增加注释

lqg 2 years ago
parent
commit
aedd16a6d1

+ 16 - 117
README.md

@@ -1,138 +1,37 @@
-# 搞事情
-
->这是一沟绝望的死水,清风吹不起半点漪沦。 在这只许州官放火不许百姓电灯的年代,我们不如一起拿起几行简单的python代码,向这死水中多扔些破铜烂铁。
-
-**我们的目标就是把这互联网搞的更乱更臭,所以我们是不被规则束缚的。今天要拿来开刀的,是邮件系统。**
-
-垃圾邮件,很多人都深受其害,但我们今天并不是要搞它。以相反的方式进行思考,我们并不讨厌它,而且欢迎它的到来。比如,我要批量注册**一万个**github账号。github通过邮箱验证就算注册成功了,这个时候,我们需要一个邮件服务器,具体流程如下:
-![](media/15338909023224.jpg)
-
-
-这个时候就想啊,能不能把邮件接收这块给自动化呢?自动化涉及两个点:
-1)要有无穷无尽的邮箱供你使用
-2)要非常容易的获得邮件内容进行解析
-
-稍作思考,一个方案就在脑海中浮现,竟然是超简单的存在。
-![](media/15338909254129.jpg)
-
-其中:
-1) 阉割的邮件系统不需要登录,只管收,不管发
-2)邮件系统可以接受带有某后缀的任意邮件
-3)提供简单的REST接口返回邮件JSON供解析
-
-下面我们直接进入正题,说一下实现方式。
+# Github批量注册
 
 # 域名解析配置
-打开域名管理,以阿里云为例,加入两条信息
 
-加入一条A记录,指向我们将要部署的服务IP地址
+打开域名管理,加入一条A记录,指向我们将要部署的服务IP地址
+
 ```
-A	mx	 6x.216.2xx.1xx
+A	mx	 185.216.200.12
 ```
 
-加入一条MX记录,指向上面配置的收邮件的域名地址。
+加入一条MX记录,指向上面配置的收邮件的域名地址
+
 ```
 MX	*	mx.sayhiai.com
 ```
 
-> 注意 `*`号,意思是所有的域名包括二级域名等,都会被收到。比如xxxx@sayhiai.com 、 xjksfdsf@dfjsdlfjsd.sayhiai.com。
-> 是不是无穷无尽?
-
-# 编写SMTPD服务器
+## 运行
 
-使用python可以很容易的实现一个SMTPD服务器,具体的是使用`aiosmtpd`库。邮件默认收到后是BASE64编码,还分很多部分和类型,解析起来还是比较麻烦的。需要猜解其编码并递归拼接邮件等。代码片段如下:
-```python
-def decode_str(s):
-    value, charset = decode_header(s)[0]
-    if charset:
-        value = value.decode(charset)
-    return value
-def guess_charset(msg):
-    charset = msg.get_charset()
-    if charset is None:
-        content_type = msg.get('Content-Type', '').lower()
-        pos = content_type.find('charset=')
-        if pos >= 0:
-            charset = content_type[pos + 8:].strip()
-    return charset
-def print_part(msg):
-    rs = ""
-    content_type = msg.get_content_type()
-    if content_type == 'text/plain' or content_type == 'text/html':
-        content = msg.get_payload(decode=True)
-        charset = guess_charset(msg)
-        if charset:
-            content = content.decode(charset)
-        rs = rs + str(content)
-    else:
-        rs = rs + str(content_type)
-    return rs
-def print_info(msg):
-    rs = ""
-    if (msg.is_multipart()):
-        parts = msg.get_payload()
-        for n, part in enumerate(parts):
-            if part.is_multipart():
-                rs = rs + print_info(part)
-            else:
-                rs = rs + print_part(part)
-    else:
-        return print_part(msg)
-    return rs
 ```
-
-# 编写REST服务
-
-解析完邮件后,我们把内容存放在sqlite3中。接下来就是编写数据接口了。
-
-我们的目的是尽量方便邮件的获取,`REST+json`是首选的。python的`flask`库无疑是最简单最适合的。
-
-```python
-import json
-from flask import Flask
-from flask import send_file
-from data import dataInstance
-app = Flask(__name__)
-dao = dataInstance
-def web_start(host, port):
-    app.run(host=host, port=port)
-@app.route('/')
-def index():
-    return send_file('static/index.html')
-@app.route('/all')
-def msg_all():
-    rows = dao.read_all()
-    return json.dumps(rows)
-@app.route('/from/<addr>')
-def msg_from(addr):
-    rows = dao.read_from(addr)
-    return json.dumps(rows)
-@app.route('/to/<addr>')
-def msg_to(addr):
-    rows = dao.read_to(addr)
-    return json.dumps(rows)
+cd my_project_dir
+virtualenv -p /opt/python/bin/python3 venv
+source venv/bin/activate
+pip install -r requirements.txt
+python main.py
 ```
-如你所见,提供了三个接口
-1)/all  获取所有邮件
-2) /from/{addr} 根据发送方查找邮件
-3) /to/{addr} 根据接收方查找邮件
-
-每次查询做多返回100条记录,反正多了你也用不着。
 
 # 试验一下
+
 使用 skdfkdsjf@sayhiai.com 注册一个账号。使用curl或者浏览器获取邮件信息:
+
 ```
 curl -XGET http://sayhiai.com:14000/to/skdfkdsjf@sayhiai.com
 ```
-或者使用 http://sayhiai.com:14000/ 在线查询一下。
-
-> 我的太慢,记得自己搭建一个啊,别忘了SMTPD的端口是25,绑定其他的是不行的
-
-# 结尾
-至此, 一个完美的闭环完成了。我记的前段时间某些同学还对微软收购github心存不满,是时候给你一个发泄的途径了,注意多弄几个ip。
 
-你瞧瞧你瞧瞧,即使github这么大的一个网站,仅仅邮箱验证就通过了,可以预见网络上有多少的网站可以使用相同的思路去搞。
-
-我已经把代码放到github上了 :) :) :).   https://github.com/lycying/crazy-email-recv-srv ,对你有帮助的话别忘了关注微信公众号`小姐姐味道`,如果顺便打赏几毛钱,那是最妙不过了。要是你干了坏事的话,就先不要留名了~
+或者使用 http://sayhiai.com:14000/ 在线查询一下。
 
-![](media/qrcode_for_gh_183eb256f8af_1280.jpg)
+> 我的太慢,记得自己搭建一个啊,别忘了SMTPD的端口是25,绑定其他的是不行的

+ 0 - 0
cfg.ini → conf/cfg.ini


+ 13 - 3
main.py

@@ -1,5 +1,14 @@
-from smtpx import CrazySrvHandler
-from web import web_start
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@Contact :   liuyuqi.gov@msn.cn
+@Time    :   2023/01/30 09:47:22
+@License :   Copyright © 2017-2022 liuyuqi. All Rights Reserved.
+@Desc    :   enter point
+'''
+
+from receive_email.smtpx import CrazySrvHandler
+from receive_email.web import web_start
 
 from aiosmtpd.controller import Controller
 from aiosmtpd.smtp import SMTP
@@ -7,7 +16,7 @@ import configparser
 
 if __name__ == "__main__":
     cf = configparser.ConfigParser()
-    cf.read("cfg.ini")
+    cf.read("conf/cfg.ini")
 
     smtpd_host = cf.get("smtpd", "host")
     smtpd_port = cf.getint("smtpd", "port")
@@ -16,6 +25,7 @@ if __name__ == "__main__":
     rest_port = cf.getint("rest", "port")
 
     handler = CrazySrvHandler()
+    # 邮件控制器
     controller = Controller(handler, hostname=smtpd_host, port=smtpd_port)
     controller.factory = lambda: SMTP(handler, enable_SMTPUTF8=True)
 

BIN
media/15338909023224.jpg


BIN
media/15338909254129.jpg


BIN
media/qrcode_for_gh_183eb256f8af_1280.jpg


+ 8 - 0
receive_email/__init__.py

@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@Contact :   liuyuqi.gov@msn.cn
+@Time    :   2023/01/14 17:30:15
+@License :   Copyright © 2017-2022 liuyuqi. All Rights Reserved.
+@Desc    :   
+'''

+ 10 - 0
data.py → receive_email/data.py

@@ -1,3 +1,12 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@Contact :   liuyuqi.gov@msn.cn
+@Time    :   2023/01/30 10:47:30
+@License :   Copyright © 2017-2022 liuyuqi. All Rights Reserved.
+@Desc    :   sqlte3 保存数据
+'''
+
 import datetime
 import sqlite3
 import json
@@ -5,6 +14,7 @@ import json
 
 class DataAccess:
     def __init__(self):
+        '''连接数据库'''
         self.conn = sqlite3.connect(":memory:", check_same_thread=False);
         c = self.conn.cursor()
         c.execute("CREATE TABLE msg(frm TEXT, to0 TEXT, tos TEXT, subject TEXT, content TEXT,createDate timestamp)");

+ 7 - 1
smtpx.py → receive_email/smtpx.py

@@ -1,10 +1,13 @@
 import email
 from email.header import decode_header
 
-from data import dataInstance
+from receive_email.data import dataInstance
 
 
 def decode_str(s):
+    '''
+    邮件内容解码
+    '''
     value, charset = decode_header(s)[0]
     if charset:
         value = value.decode(charset)
@@ -12,6 +15,9 @@ def decode_str(s):
 
 
 def guess_charset(msg):
+    '''
+    检测邮件编码
+    '''
     charset = msg.get_charset()
     if charset is None:
         content_type = msg.get('Content-Type', '').lower()

+ 3 - 1
web.py → receive_email/web.py

@@ -1,7 +1,7 @@
 import json
 from flask import Flask
 from flask import send_file
-from data import dataInstance
+from receive_email.data import dataInstance
 
 app = Flask(__name__)
 dao = dataInstance
@@ -32,3 +32,5 @@ def msg_from(addr):
 def msg_to(addr):
     rows = dao.read_to(addr)
     return json.dumps(rows)
+
+

+ 2 - 1
requirements.txt

@@ -1,2 +1,3 @@
 aiosmtpd
-flask
+flask==1.1.2
+# sqlite3

+ 8 - 0
setup.py

@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@Contact :   liuyuqi.gov@msn.cn
+@Time    :   2023/01/14 16:57:25
+@License :   Copyright © 2017-2022 liuyuqi. All Rights Reserved.
+@Desc    :   安装
+'''

+ 97 - 109
static/index.html

@@ -1,124 +1,112 @@
 <html>
 
-    <head>
-        <title>crazy email recv srv</title>
-        <link href="https://cdn.bootcss.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
-        <link href="https://cdn.bootcss.com/bootstrap-table/1.12.1/bootstrap-table.min.css" rel="stylesheet">
-    </head>
-
-    <body>
-        <div class="container">
-            <div class="jumbotron" style="padding-top:2px;padding-bottom:2px">
-                <h1>Crazy Email Reciver Service</h1>
-                <p class="lead">Use this mock your email server , just for recive . USAGE: such as batch register . This page only show the most recently emails ( about 100 items) 
-                <button  type="submit" class="btn btn-default">github</button> <a target="_blank" href="https://github.com/lycying/crazy-email-recv-srv">https://github.com/lycying/crazy-email-recv-srv</a>
-                </p>
-            </div>
-            <div id="toolbar">
-                <div class="form-inline" role="form">
-                    <div class="form-group">
-                        <input id="from" class="form-control" type="text" placeholder="From">
-                    </div>
-                    <button id="from_btn" type="submit" class="btn btn-success">Search</button>
-
-                    &nbsp;
-                    &nbsp;
-                    &nbsp;
-                    &nbsp;
-                    &nbsp;
-                    &nbsp;
-
-
-                    <div class="form-group">
-                        <input id="to" class="form-control" type="text" placeholder="To">
-                    </div>
-                    <button id="to_btn" type="submit" class="btn btn-success">Search</button>
+<head>
+    <title>crazy email recv srv</title>
+    <link href="https://cdn.bootcss.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
+    <link href="https://cdn.bootcss.com/bootstrap-table/1.12.1/bootstrap-table.min.css" rel="stylesheet">
+</head>
+
+<body>
+    <div class="container">
+        <div class="jumbotron" style="padding-top:2px;padding-bottom:2px">
+            <h1>Crazy Email Reciver Service</h1>
+        </div>
+        <div id="toolbar">
+            <div class="form-inline" role="form">
+                <div class="form-group">
+                    <input id="from" class="form-control" type="text" placeholder="From">
                 </div>
-
+                <button id="from_btn" type="submit" class="btn btn-success">Search</button>
+                &nbsp;
+                &nbsp;
+                &nbsp;
+                &nbsp;
+                &nbsp;
+                &nbsp;
+                <div class="form-group">
+                    <input id="to" class="form-control" type="text" placeholder="To">
+                </div>
+                <button id="to_btn" type="submit" class="btn btn-success">Search</button>
             </div>
-            <table id="table"
-                   data-toolbar="#toolbar"
-                   data-show-columns="true">
-                <thead>
-                    <tr>
-                        <th data-field="from">From</th>
-                        <th data-field="to0">To[0]</th>
-                        <th data-field="to">To[ALL]</th>
-                        <th data-field="subject">Subject</th>
-                        <th data-field="content">Content</th>
-                        <th data-field="time">Date</th>
-
-                    </tr>
-                </thead>
-            </table>
 
-            <div class="jumbotron">
-                <h2>API</h2>
-                <b>/all </b>  get all emails (limit 100) <br/>
-                <b>/from/{addr}</b>  get emails from addr (limit 100)<br/>
-                <b>/to/{addr}</b>  get emails to addr(limit 100)<br/>
-                <p class="lead">
+        </div>
+        <table id="table" data-toolbar="#toolbar" data-show-columns="true">
+            <thead>
+                <tr>
+                    <th data-field="from">From</th>
+                    <th data-field="to0">To[0]</th>
+                    <th data-field="to">To[ALL]</th>
+                    <th data-field="subject">Subject</th>
+                    <th data-field="content">Content</th>
+                    <th data-field="time">Date</th>
+
+                </tr>
+            </thead>
+        </table>
+
+        <div class="jumbotron">
+            <h2>API</h2>
+            <b>/all </b> get all emails (limit 100) <br />
+            <b>/from/{addr}</b> get emails from addr (limit 100)<br />
+            <b>/to/{addr}</b> get emails to addr(limit 100)<br />
+            <p class="lead">
                 example:
-                <pre>
- [{
-		"from": "a@example.com",
-		"to0": "b@example.com",
-		"to": ["b@example.com"],
-		"subject": "A test",
-		"content": "xxxxxxxxxxxxxxxxx*
-}]
+            <pre>
+                [{
+                        "from": "a@example.com",
+                        "to0": "b@example.com",
+                        "to": ["b@example.com"],
+                        "subject": "A test",
+                        "content": "xxxxxxxxxxxxxxxxx*
+                }]
                 </pre>
-                </p>
-            </div>
+            </p>
         </div>
+    </div>
 
-        <script src="https://cdn.bootcss.com/jquery/1.11.0/jquery.min.js"></script>
-        <script src="https://cdn.bootcss.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
-        <script src="https://cdn.bootcss.com/bootstrap-table/1.12.1/bootstrap-table.min.js"></script>
-        <script>
+    <script src="https://cdn.bootcss.com/jquery/1.11.0/jquery.min.js"></script>
+    <script src="https://cdn.bootcss.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
+    <script src="https://cdn.bootcss.com/bootstrap-table/1.12.1/bootstrap-table.min.js"></script>
+    <script>
 
-            $.getJSON("all",function(data){
-                var $table = $('#table');
-                $table.bootstrapTable({data: data});
-            });
-
-$("#from_btn").click(function(){
-    from=$("#from").val();
-    if(from==""){
-        $.getJSON("all",function(data){
-            var $table = $('#table');
-            $table.bootstrapTable('removeAll');
-            $table.bootstrapTable('append',data);
-        });
-    }else{
-        $.getJSON("from/"+from,function(data){
+        $.getJSON("all", function (data) {
             var $table = $('#table');
-            $table.bootstrapTable('removeAll');
-            $table.bootstrapTable('append',data);
+            $table.bootstrapTable({data: data});
         });
-    }
-});
-$("#to_btn").click(function(){
-    from=$("#to").val();
-    if(from==""){
-        $.getJSON("all",function(data){
-            var $table = $('#table');
-            $table.bootstrapTable('removeAll');
-            $table.bootstrapTable('append',data);
+
+        $("#from_btn").click(function () {
+            from = $("#from").val();
+            if (from == "") {
+                $.getJSON("all", function (data) {
+                    var $table = $('#table');
+                    $table.bootstrapTable('removeAll');
+                    $table.bootstrapTable('append', data);
+                });
+            } else {
+                $.getJSON("from/" + from, function (data) {
+                    var $table = $('#table');
+                    $table.bootstrapTable('removeAll');
+                    $table.bootstrapTable('append', data);
+                });
+            }
         });
-    }else{
-        $.getJSON("to/"+from,function(data){
-            var $table = $('#table');
-            $table.bootstrapTable('removeAll');
-            $table.bootstrapTable('append',data);
+        $("#to_btn").click(function () {
+            from = $("#to").val();
+            if (from == "") {
+                $.getJSON("all", function (data) {
+                    var $table = $('#table');
+                    $table.bootstrapTable('removeAll');
+                    $table.bootstrapTable('append', data);
+                });
+            } else {
+                $.getJSON("to/" + from, function (data) {
+                    var $table = $('#table');
+                    $table.bootstrapTable('removeAll');
+                    $table.bootstrapTable('append', data);
+                });
+            }
         });
-    }
-});
-
-
-
-
-        </script>
-    </body>
+    </script>
+</body>
 
-</html>
+</html>

+ 0 - 12
tests/send_test.py

@@ -1,12 +0,0 @@
-from smtplib import SMTP as Client
-
-client = Client("localhost", 8025)
-
-r = client.sendmail('a@example.com', ['b@example.com'], """\
-From: Anne Person <anne@example.com>
-To: Bart Person <bart@example.com>
-Subject: A test
-Message-ID: <ant>
-
-Hi Bart, this is Anne.
-""")

+ 0 - 3
tests/web_test.py

@@ -1,3 +0,0 @@
-from web import web_start
-
-web_start()