This commit is contained in:
ouczbs 2024-02-15 15:03:33 +08:00
parent baa77f4468
commit b0007f4cfd
21 changed files with 226 additions and 773 deletions

BIN
client Normal file

Binary file not shown.

BIN
client.exe Normal file

Binary file not shown.

View File

@ -1,21 +0,0 @@
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
resp, err := http.Get("https://zh.xhamster.com/?ref=porndude")
if err != nil {
fmt.Println("http get error", err)
return
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("read error", err)
return
}
fmt.Println(string(body))
}

View File

@ -6,46 +6,49 @@ import (
)
type UClientProxy struct {
ServerConn *UPacketConnection
serverAddr string
clientAddr string
}
func NewClientProxy() *UClientProxy {
return &UClientProxy{}
func (client *UClientProxy) NewClientConnection() *PacketConnect {
conn, err := net.Dial("tcp", client.clientAddr)
if err != nil {
zlog.Infof("connect local client error: %s %s", err.Error(), client.clientAddr)
return nil
}
return NewPacketConnect(conn, "local")
}
func (client *UClientProxy) NewTcpConnection(id uint32) *PacketConnect {
conn, err := net.Dial("tcp", client.serverAddr)
if err != nil {
zlog.Infof("connect server error: %s", err.Error())
}
remote := NewPacketConnect(conn, "remote")
remote.WriteHeader(id)
if id == RemoteID {
return remote
}
local := client.NewClientConnection()
if local == nil {
err = remote.Close()
return nil
}
go local.Forward(remote, 0)
go remote.Forward(local, 0)
return nil
}
func (client *UClientProxy) ServeTCP(serverAddr string, clientAddr string) error {
conn, err := net.Dial("tcp", serverAddr)
if err != nil {
return err
}
zlog.Infof("connect server %s", serverAddr)
client.ServerConn = NewPacketConnection(conn)
_, err = client.ServerConn.Write([]byte("anki"))
if err != nil {
return err
}
client.serverAddr = serverAddr
client.clientAddr = clientAddr
RemoteConn := client.NewTcpConnection(RemoteID)
zlog.Infof("connect to server %s", RemoteConn.Name())
for {
data := make([]byte, 4)
_, err := client.ServerConn.Read(data, 0, 4)
if err != nil {
return err
}
if string(data) != "anki" {
data := RemoteConn.ReadHeader()
if string(data[:4]) != "anki" {
zlog.Error("rcv package error:", data)
client.ServerConn.Clear()
continue
}
conn, err := net.Dial("tcp", clientAddr)
if err != nil {
zlog.Error("connect local anki error: ", err.Error(), clientAddr)
client.ServerConn.ForwardError(err)
continue
}
pc := NewPacketConnection(conn)
client.ServerConn.Forward(pc)
pc.Forward(client.ServerConn)
err = pc.Close()
if err != nil {
zlog.Error("close local anki error: ", err.Error())
}
id := packetEndian.Uint32(data[4:])
go client.NewTcpConnection(id)
}
}

87
proxy/packet_connect.go Normal file
View File

@ -0,0 +1,87 @@
package proxy
import (
"encoding/binary"
"net"
"strconv"
"time"
)
var (
packetEndian = binary.LittleEndian
RemoteID uint32 = 1
sid = RemoteID
maxSid uint32 = 1024 * 1024
HeaderSize = 16
Magic = "anki"
InitBuf = func() []byte {
buf := make([]byte, HeaderSize)
copy(buf[:len(Magic)], Magic)
return buf
}()
)
func IncID() uint32 {
if sid > maxSid {
sid = RemoteID
}
sid++
return sid
}
type PacketConnect struct {
net.Conn
header []byte
id uint32
readErr error
writeErr error
name string
}
func NewPacketConnect(conn net.Conn, name string) *PacketConnect {
pc := &PacketConnect{Conn: conn, header: make([]byte, HeaderSize)}
pc.SetRemote(name, 0)
copy(pc.header, InitBuf)
return pc
}
func (pc *PacketConnect) Name() string {
return pc.name
}
func (pc *PacketConnect) SetRemote(name string, id uint32) {
pc.id = id
pc.name = "(" + name + ")" + strconv.Itoa(int(id)) + "::" + pc.RemoteAddr().String()
}
func (pc *PacketConnect) Write(data []byte) int {
n, err := pc.Conn.Write(data)
pc.writeErr = err
return n
}
func (pc *PacketConnect) Read(data []byte) int {
n, err := pc.Conn.Read(data)
pc.readErr = err
return n
}
func (pc *PacketConnect) ReadHeader() []byte {
pc.Read(pc.header)
return pc.header
}
func (pc *PacketConnect) WriteHeader(id uint32) {
packetEndian.PutUint32(pc.header[4:8], id)
pc.Write(pc.header)
}
func (pc *PacketConnect) Forward(dst *PacketConnect, rn int) {
if rn > 0 {
dst.Write(pc.header[:rn])
}
defer func() {
_ = pc.Close()
}()
data := make([]byte, 1024)
for pc.readErr == nil && dst.writeErr == nil {
_ = pc.SetReadDeadline(time.Now().Add(time.Second))
n := pc.Read(data)
rn += n
dst.Write(data[:n])
}
}

View File

@ -1,85 +0,0 @@
package proxy
import (
"net"
"zproxy/zlog"
)
type UPacketConnection struct {
*UHttpRequest
}
// 创建连接的方法
func NewPacketConnection(conn net.Conn) *UPacketConnection {
//初始化Conn属性
c := &UPacketConnection{
UHttpRequest: NewHttpRequest(conn),
}
return c
}
func (pc *UPacketConnection) Forward(target *UPacketConnection) {
pc.DataSize = 0
pc.IsLoadHeader = false
for !pc.IsLoadHeader {
data, err := pc.ReadLine()
if err != nil {
zlog.Error("read header line error: ", err.Error())
return
}
_, err = target.Write(data)
if err != nil {
zlog.Error("write header line error: ", err.Error())
return
}
}
if pc.DataSize == 0 {
return
}
data := make([]byte, 1024)
for pc.DataSize > 0 {
size := min(pc.DataSize, 1024)
n, err := pc.Read(data, 0, size)
if err != nil {
zlog.Error("read body error: ", err.Error())
return
}
pc.DataSize -= n
zlog.Infof("read body %d %s", n, data[:n])
_, err = target.Write(data[:n])
if err != nil {
zlog.Error("write body error: ", err.Error())
return
}
}
}
func (pc *UPacketConnection) Close() error {
err := pc.Conn.Close()
return err
}
func (pc *UPacketConnection) ForwardError(err error) {
pc.DataSize = 0
pc.IsLoadHeader = false
zlog.Infof("forward error: ", err.Error())
for !pc.IsLoadHeader {
_, err := pc.ReadLine()
if err != nil {
zlog.Error("read header line error: ", err.Error())
return
}
}
for pc.DataSize > 0 {
data := make([]byte, 1024)
size := min(pc.DataSize, 1024)
n, err := pc.Read(data, 0, size)
if err != nil {
zlog.Error("Read body error: ", err.Error())
return
}
pc.DataSize -= n
}
err = pc.WriteError(err)
if err != nil {
zlog.Error("write error http error: ", err.Error())
return
}
}

View File

@ -1,91 +0,0 @@
package proxy
import (
"bytes"
"io"
)
func min(a int, b int) int {
if a < b {
return a
}
return b
}
type UReader struct {
io io.Reader
buf []byte
r, w int
err error
}
func NewReader(io io.Reader) *UReader {
return &UReader{
io: io,
buf: make([]byte, 4096),
r: 0,
w: 0,
}
}
func (b *UReader) Read(data []byte, s int, e int) (int, error) {
n := e - s
rn := 0
for rn < n {
d := min(b.w-b.r, n-rn)
if d > 0 {
copy(data[s+rn:s+rn+d], b.buf[b.r:b.r+d])
b.r += d
rn += d
if rn >= n {
break
}
}
err := b.fill()
if err != nil {
return rn, err
}
}
return rn, nil
}
func (b *UReader) ReadLine() ([]byte, error) {
line, err := b.ReadSlice('\n')
return line, err
}
func (b *UReader) ReadSlice(delim byte) ([]byte, error) {
s := 0 // search start index
for {
// Search buffer.
if i := bytes.IndexByte(b.buf[b.r+s:b.w], delim); i >= 0 {
i += s + 1
b.r += i
return b.buf[b.r-i : b.r], nil
}
err := b.fill()
if err != nil {
return b.buf[b.r:], err
}
}
}
func (b *UReader) fill() error {
d := b.w - b.r
if d >= len(b.buf) {
b.r = 0
b.w = 0
return ErrBufferFull
}
// Slide existing data to beginning.
if b.r > 0 {
copy(b.buf, b.buf[b.r:b.w])
b.w -= b.r
b.r = 0
}
// Read new data: try a limited number of times.
n, err := b.io.Read(b.buf[b.w:])
b.w += n
return err
}
func (b *UReader) Clear() {
b.r = 0
b.w = 0
}

View File

@ -1,80 +0,0 @@
package proxy
import (
"bytes"
"net"
"strconv"
"strings"
)
type UHttpRequest struct {
Conn net.Conn
io *UReader
IsLoadHeader bool
DataSize int
}
func NewHttpRequest(conn net.Conn) *UHttpRequest {
return &UHttpRequest{
Conn: conn,
io: NewReader(conn),
IsLoadHeader: false,
DataSize: 0,
}
}
func (req *UHttpRequest) ReadLine() ([]byte, error) {
line, err := req.io.ReadLine()
if err != nil {
return line, err
}
if !req.IsLoadHeader && bytes.Equal(line, []byte("\r\n")) {
req.IsLoadHeader = true
}
if !req.IsLoadHeader {
k, v, ok := bytes.Cut(line, []byte(":"))
if !ok {
return line, err
}
if bytes.Equal(k, []byte("Content-Length")) {
nv := strings.Trim(string(v), " \r\n")
n, err := strconv.ParseUint(nv, 10, 63)
if err != nil {
return line, err
}
req.DataSize = int(n)
}
}
return line, err
}
func (req *UHttpRequest) Read(data []byte, s int, e int) (int, error) {
return req.io.Read(data, s, e)
}
func (req *UHttpRequest) Write(data []byte) (int, error) {
return req.Conn.Write(data)
}
func (req *UHttpRequest) WriteError(err error) error {
return req.WriteHttp([]byte("HTTP/1.1 200 OK\r\n"), []byte(err.Error()))
}
func (req *UHttpRequest) WriteHttp(header []byte, data []byte) error {
_, err := req.Write(header)
if err != nil {
return err
}
var bufBody bytes.Buffer
bufBody.WriteString("{\n \"error\" : \"")
bufBody.WriteString(string(data))
bufBody.WriteString("\"\n}")
var bufWrap bytes.Buffer
bufWrap.WriteString("Content-Length:")
bufWrap.WriteString(strconv.Itoa(bufBody.Len()))
bufWrap.WriteString("\r\n\r\n")
_, err = req.Write(bufWrap.Bytes())
if err != nil {
return err
}
_, err = req.Write(bufBody.Bytes())
return err
}
func (req *UHttpRequest) Clear() {
req.io.Clear()
}

View File

@ -6,66 +6,85 @@ import (
)
type UServerProxy struct {
AnkiConn *UPacketConnection
RemoteMap map[uint32]*PacketConnect
ClientMap map[uint32]*PacketConnect
RemoteConn *PacketConnect
MessageQueue chan uint32
}
func NewServerProxy() *UServerProxy {
return &UServerProxy{}
return &UServerProxy{
RemoteMap: make(map[uint32]*PacketConnect),
ClientMap: make(map[uint32]*PacketConnect),
MessageQueue: make(chan uint32, 32),
}
}
func (server *UServerProxy) NewTcpConnection(client *UPacketConnection) {
defer func() {
if client == server.AnkiConn {
return
func (server *UServerProxy) NewTcpConnection(client *PacketConnect) {
data := client.ReadHeader()
if string(data[:4]) == "anki" {
id := packetEndian.Uint32(data[4:8])
client.SetRemote("remote", id)
if id == RemoteID {
if server.RemoteConn != nil && server.RemoteConn != client {
_ = server.RemoteConn.Close()
}
server.RemoteConn = client
zlog.Infof("rcv %d %s", id, client.Name())
} else {
server.RemoteMap[id] = client
server.MessageQueue <- id
}
err := client.Close()
if err != nil {
zlog.Error("close client error: ", err)
return
}
if server.RemoteConn == nil {
return
}
id := IncID()
server.RemoteConn.WriteHeader(id)
server.ClientMap[id] = client
zlog.Infof("%d %s", id, data)
}
func (server *UServerProxy) MessageLoop() {
for {
select {
case mid := <-server.MessageQueue:
remote := server.RemoteMap[mid]
client := server.ClientMap[mid]
if client == nil || remote == nil {
server.RemoteMap[mid] = nil
server.ClientMap[mid] = nil
continue
}
go func() {
client.Forward(remote, HeaderSize)
server.ClientMap[mid] = nil
}()
go func() {
remote.Forward(client, 0)
server.RemoteMap[mid] = nil
}()
}
}()
data := []byte("anki0000")
_, err := client.Read(data, 4, 8)
if err != nil {
zlog.Error("read client error: ", client.Conn.RemoteAddr(), err.Error())
return
}
zlog.Infof("new client %s %s", client.Conn.RemoteAddr(), data[4:])
if string(data[4:]) == "anki" {
server.AnkiConn = client
return
}
if server.AnkiConn == nil {
client.ForwardError(ErrNoAnkiProxy)
return
}
_, err = server.AnkiConn.Write(data)
if err != nil {
return
}
client.Forward(server.AnkiConn)
server.AnkiConn.Forward(client)
}
func (server *UServerProxy) ServeTCP(listenAddr string) error {
// listenAddr 只能填端口号
ln, err := net.Listen("tcp", listenAddr)
if err != nil {
zlog.Error("listen server error: ", err.Error(), listenAddr)
return err
zlog.Error("listen error:", err.Error())
}
zlog.Infof("listen server %s", listenAddr)
zlog.Infof("listen %s", ln.Addr())
defer func(ln net.Listener) {
err := ln.Close()
if err != nil {
zlog.Error("close listen server error: ", err.Error(), listenAddr)
zlog.Error("close client error: ", err.Error())
}
}(ln)
go server.MessageLoop()
for {
conn, err := ln.Accept()
if err != nil {
if IsTimeoutError(err) {
continue
}
return err
}
go server.NewTcpConnection(NewPacketConnection(conn))
server.NewTcpConnection(NewPacketConnect(conn, "client"))
}
}

View File

@ -1,37 +0,0 @@
package proxy
type timeoutError interface {
Timeout() bool // Is it a timeout error
}
// fundamental is an error that has a message and a stack, but no caller.
type errors struct {
msg string
}
func (e errors) Error() string {
return e.msg
}
func NewError(msg string) error {
return errors{msg: msg}
}
var (
ErrBufferFull = NewError("read: buffer full")
ErrNoAnkiProxy = NewError("anki: no client proxy connect")
)
var (
ServerAddr = ":8765"
RemoteServerAddr = "175.24.226.114" + ServerAddr
ClientAddr = "127.0.0.1:8765"
)
// IsTimeoutError checks if the error is a timeout error
func IsTimeoutError(err error) bool {
if err == nil {
return false
}
ne, ok := err.(timeoutError)
return ok && ne.Timeout()
}

View File

@ -1,155 +0,0 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 13,
"id": "1664172b",
"metadata": {},
"outputs": [],
"source": [
"from http2 import *\n",
"class AnkiClient(Http):\n",
" def __init__(self):\n",
" Http.__init__(self)\n",
" self.url = 'http://127.0.0.1:8764'\n",
" self.version = None\n",
" def api(self, data):\n",
" print(data)\n",
" data = json.dumps(data)\n",
" res = self._post(self.url, data)\n",
" return res\n",
" def make_version(self):\n",
" self.version = self.api({\"action\":\"version\"})\n",
" return self.version\n",
" def deckNames(self):\n",
" return self.api({\"action\":\"deckNames\"})\n",
" def modelNames(self):\n",
" return self.api({\"action\":\"modelNames\"})\n",
" def modelFieldNames(self, modelName):\n",
" return self.api({\"action\":\"modelFieldNames\", \"params\" :{\"modelName\" : modelName}})\n",
" def addNote(self, note):\n",
" return self.api({\"action\":\"addNote\", \"params\" : {\"note\": note}})"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "ee987c62",
"metadata": {},
"outputs": [],
"source": [
"anki = AnkiClient()"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "58e77a6b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'action': 'deckNames'}\n",
"_post http://127.0.0.1:8764\n"
]
},
{
"data": {
"text/plain": [
"b'[\"Git\", \"\\\\u53e5\\\\u7d20\", \"\\\\u793a\\\\u4f8b\\\\u724c\\\\u7ec4\", \"\\\\u7cfb\\\\u7edf\\\\u9ed8\\\\u8ba4\", \"\\\\u82f1\\\\u8bed\", \"\\\\u8d56\\\\u4e16\\\\u96c4\\\\u97f3\\\\u6807\", \"\\\\u97f3\\\\u6807\"]'"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t = anki.deckNames()\n",
"t"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "c3b5b237",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"b'{\\n error = \"anki: no client proxy connect\"\\n}'"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "53bd0e19",
"metadata": {},
"outputs": [],
"source": [
"b = b'{\\n error = \"anki: no client proxy connect\"\\n}'"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "9d89217c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" error = \"anki: no client proxy connect\"\n",
"}\n"
]
}
],
"source": [
"print(b.decode())"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "203e9f90",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@ -1,84 +0,0 @@
import inspect
import json, requests , zlib
from functools import wraps
from http.cookiejar import LWPCookieJar
import http.cookiejar as cookielib
default_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\
/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
class Session(requests.Session):
def __init__(self, headers={}, cookie_file=None):
requests.Session.__init__(self)
if cookie_file:
self.cookies = LWPCookieJar(filename = cookie_file)
self.cookies.load(ignore_discard = True)
self.update(headers)
self.auth = ('user', 'pass')
def save(self, filename = None):
self.cookies.save()
def update(self, headers):
self.headers.update(headers)
def http_error(code):
def _with(func):
@wraps(func)
def _deco(self, url):
return func(self, url)
_deco.__error_code__ = code
return _deco
return _with
class Http():
def __init__(self, headers = default_headers, session = None):
session = session or Session()
session.update(headers)
self.session = session
self._type = 'str'
self._error_dict = self._get_error_dict()
def _gets(self, url, data = None):
res = self.session.get(url, params = data)
self._error(res, url)
return self._res_data(res, self._type)
def _posts(self, url, data = None):
res = self.session.get(url, params = data)
self._error(res, url)
return self._res_data(res, self._type)
def _get(self, url, data = None):
print("_get", url)
res = requests.get(url, params = data, headers = self.session.headers)
self._error(res, url)
return self._res_data(res, self._type)
def _post(self, url, data):
print("_post", url)
res = requests.get(url, data = data, headers = self.session.headers)
self._error(res, url)
return self._res_data(res, self._type)
def _get_error_dict(self):
error_dict = {}
methods = inspect.getmembers(self, predicate=inspect.ismethod)
for method in methods:
error_code = getattr(method[1], '__error_code__', None)
if error_code:
error_dict[error_code] = method[1]
return error_dict
def _error(self, res, url):
code = res.status_code
if code == 200:
return
print(res.content)
if code in self._error_dict:
self._error_dict[code](url)
return
raise RuntimeError(code + '- unknown error ' + url)
@http_error(403)
def _error_403(self, url):
raise RuntimeError('error:403 - Forbidden ' + url)
@http_error(404)
def _error_404(self, url):
raise RuntimeError('error:404 - Not Found ' + url)
def _res_data(self, res, _type):
# encoding = None
# if 'Content-Encoding' in res.headers:
# encoding = res.headers['Content-Encoding']
# if encoding == 'gzip':
# res.content = zlib.decompress(res.content, 16 + zlib.MAX_WBITS)
# if _type == 'json':
# return json.loads(res.content)
return res.content

View File

@ -1,64 +0,0 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "3f40720a",
"metadata": {},
"outputs": [],
"source": [
"import requests"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "d2986616",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Response [200]>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"requests.get(\"http://localhost:8080/\",data = \"helloworld\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7f2dd59b",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@ -1,14 +1,41 @@
package main
import (
"flag"
"strconv"
"zproxy/proxy"
"zproxy/zlog"
)
var (
//ServerAddr = "127.0.0.1"
//ServerPort = 8765
ServerAddr = "175.24.226.114"
ServerPort = 7860
RemoteAddr = "127.0.0.1"
RemotePort = 7860
)
func main() {
client := proxy.NewClientProxy()
err := client.ServeTCP(proxy.RemoteServerAddr, proxy.ClientAddr)
client := &proxy.UClientProxy{}
err := client.ServeTCP(ServerAddr+":"+strconv.Itoa(ServerPort), RemoteAddr+":"+strconv.Itoa(RemotePort))
if err != nil {
zlog.Error("exist client remote proxy: ", err.Error())
zlog.Error("exist server proxy: ", err.Error())
return
}
}
func init() {
_addr := flag.String("addr", ServerAddr, "server addr")
_port := flag.Int("port", ServerPort, "listen port")
remoteAddr := flag.String("remote_addr", RemoteAddr, "server addr")
remotePort := flag.Int("remote_port", RemotePort, "listen port")
flag.Parse()
ServerAddr = *_addr
ServerPort = *_port
RemoteAddr = *remoteAddr
RemotePort = *remotePort
}

View File

@ -1,15 +1,30 @@
package main
import (
"flag"
"strconv"
"zproxy/proxy"
"zproxy/zlog"
)
var (
//这里只有本地服务器可以访问,传0.0.0.0或空则支持所有连接
ServerAddr = "127.0.0.1"
ServerPort = 8765
)
func main() {
server := proxy.NewServerProxy()
err := server.ServeTCP(proxy.ServerAddr)
err := server.ServeTCP(ServerAddr + ":" + strconv.Itoa(ServerPort))
if err != nil {
zlog.Error("exist server proxy: ", err.Error())
return
}
}
func init() {
_addr := flag.String("addr", ServerAddr, "server addr")
_port := flag.Int("port", ServerPort, "listen port")
flag.Parse()
ServerAddr = *_addr
ServerPort = *_port
}

View File

@ -1,11 +0,0 @@
package main
import "net/http"
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("ok"))
})
http.ListenAndServe(":8080", nil)
}

BIN
server Normal file

Binary file not shown.

BIN
server.exe Normal file

Binary file not shown.

View File

@ -1,70 +0,0 @@
from .http import *
import json,functools
class util:
def api(func):
@functools.wraps(func)
def wrapper(self,**kwargs):
self._api({"params" : kwargs , "action":func.__name__ })
self.res = func(self, **kwargs) or self.res
return self.res
return wrapper
class AnkiClient(Http):
util = util
def __init__(self, url = None):
Http.__init__(self)
self.url = url or 'http://127.0.0.1:8765'
self._version = None
self.res = None
def _api(self, data):
if self._version and type(self._version) == int:
data["version"] = self._version
data = json.dumps(data)
res = self._post(self.url, data)
self.res = json.loads(res)
return self.res
@util.api
def version(self):
self._version = self.res
pass
@util.api
def deckNames(self):
pass
@util.api
def modelNames(self):
pass
@util.api
def modelFieldNames(self, modelName = "示例牌组"):
pass
@util.api
def modelFieldDescriptions(self, modelName = "示例牌组"):
pass
@util.api
def modelTemplates(self, modelName = "示例牌组"):
pass
@util.api
def addNote(self, note = {}):
pass
@util.api
def findNotes(self, query = "note:basic"):
pass
@util.api
def updateNote(self, note = {}):
pass
@util.api
def updateNoteTags(self, note = {}, tags = []):
pass
@util.api
def notesInfo(self, notes = []):
pass
@util.api
def findCards(self, query = "deck:示例牌组"):
pass
@util.api
def cardsInfo(self, cards = []):
pass
@util.api
def updateNoteFields(self, note = {}):
pass
@util.api
def createModel(self, modelName = "basic", inOrderFields = {}, cardTemplates = {}, css = None, isCloze = False):
pass