├── src
├── evernote
│ ├── edam
│ │ ├── __init__.py
│ │ ├── error
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ └── ttypes.py
│ │ ├── type
│ │ │ ├── __init__.py
│ │ │ └── constants.py
│ │ ├── limits
│ │ │ ├── __init__.py
│ │ │ ├── ttypes.py
│ │ │ └── constants.py
│ │ ├── notestore
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ └── NoteStore-remote
│ │ └── userstore
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ ├── UserStore-remote
│ │ │ └── ttypes.py
│ └── __init__.py
└── thrift
│ ├── __init__.py
│ ├── server
│ ├── __init__.py
│ ├── THttpServer.py
│ ├── TServer.py
│ └── TNonblockingServer.py
│ ├── transport
│ ├── __init__.py
│ ├── THttpClient.py
│ ├── TSocket.py
│ ├── TTwisted.py
│ └── TTransport.py
│ ├── protocol
│ ├── __init__.py
│ ├── TProtocol.py
│ ├── TBinaryProtocol.py
│ └── fastbinary.c
│ ├── TSCons.py
│ ├── TSerialization.py
│ └── Thrift.py
├── setup.py
└── README.md
/src/evernote/edam/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/evernote/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = '1.20'
2 |
--------------------------------------------------------------------------------
/src/evernote/edam/error/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['ttypes', 'constants']
2 |
--------------------------------------------------------------------------------
/src/evernote/edam/type/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['ttypes', 'constants']
2 |
--------------------------------------------------------------------------------
/src/evernote/edam/limits/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['ttypes', 'constants']
2 |
--------------------------------------------------------------------------------
/src/evernote/edam/notestore/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['ttypes', 'constants', 'NoteStore']
2 |
--------------------------------------------------------------------------------
/src/evernote/edam/userstore/__init__.py:
--------------------------------------------------------------------------------
1 | __all__ = ['ttypes', 'constants', 'UserStore']
2 |
--------------------------------------------------------------------------------
/src/evernote/edam/error/constants.py:
--------------------------------------------------------------------------------
1 | #
2 | # Autogenerated by Thrift
3 | #
4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5 | #
6 |
7 | from thrift.Thrift import *
8 | from ttypes import *
9 |
10 |
--------------------------------------------------------------------------------
/src/evernote/edam/notestore/constants.py:
--------------------------------------------------------------------------------
1 | #
2 | # Autogenerated by Thrift
3 | #
4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5 | #
6 |
7 | from thrift.Thrift import *
8 | from ttypes import *
9 |
10 |
--------------------------------------------------------------------------------
/src/evernote/edam/userstore/constants.py:
--------------------------------------------------------------------------------
1 | #
2 | # Autogenerated by Thrift
3 | #
4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5 | #
6 |
7 | from thrift.Thrift import *
8 | from ttypes import *
9 |
10 | EDAM_VERSION_MAJOR = 1
11 |
12 | EDAM_VERSION_MINOR = 20
13 |
14 |
--------------------------------------------------------------------------------
/src/evernote/edam/type/constants.py:
--------------------------------------------------------------------------------
1 | #
2 | # Autogenerated by Thrift
3 | #
4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5 | #
6 |
7 | from thrift.Thrift import *
8 | from ttypes import *
9 |
10 | EDAM_NOTE_SOURCE_WEB_CLIP = "web.clip"
11 |
12 | EDAM_NOTE_SOURCE_MAIL_CLIP = "mail.clip"
13 |
14 | EDAM_NOTE_SOURCE_MAIL_SMTP_GATEWAY = "mail.smtp"
15 |
16 |
--------------------------------------------------------------------------------
/src/evernote/edam/limits/ttypes.py:
--------------------------------------------------------------------------------
1 | #
2 | # Autogenerated by Thrift
3 | #
4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5 | #
6 |
7 | from thrift.Thrift import *
8 |
9 | from thrift.transport import TTransport
10 | from thrift.protocol import TBinaryProtocol
11 | try:
12 | from thrift.protocol import fastbinary
13 | except:
14 | fastbinary = None
15 |
16 |
17 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | # Setup script for Evernote API package.
2 |
3 | from setuptools import setup, find_packages
4 |
5 |
6 | setup(
7 | name = 'evernote',
8 | version = '1.20',
9 | author = 'Evernote Corporation',
10 | author_email = 'en-support@evernote.com',
11 | url = 'http://www.evernote.com/about/developer/api/',
12 | description = 'Python bindings to the Evernote API.',
13 | packages = find_packages('src'),
14 | package_dir = {'': 'src'},
15 | )
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | evernote-python-api
2 | ===================
3 |
4 | Python bindings to the Evernote API.
5 | ------------------------------------
6 |
7 | This is an unofficial package. The code herein is written by Evernote and is
8 | owned by them. More information can be found at http://www.evernote.com/about/developer/api/.
9 |
10 | Greplin has made these additions:
11 |
12 | * a setup.py file
13 | * version info at src/evernote/__init__.py
14 | * this README.md file
15 |
16 | These additions are licensed under the Apache 2 license.
17 |
--------------------------------------------------------------------------------
/src/thrift/__init__.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | __all__ = ['Thrift', 'TSCons']
21 |
--------------------------------------------------------------------------------
/src/thrift/server/__init__.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | __all__ = ['TServer', 'TNonblockingServer']
21 |
--------------------------------------------------------------------------------
/src/thrift/transport/__init__.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | __all__ = ['TTransport', 'TSocket', 'THttpClient']
21 |
--------------------------------------------------------------------------------
/src/thrift/protocol/__init__.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | __all__ = ['TProtocol', 'TBinaryProtocol', 'fastbinary']
21 |
--------------------------------------------------------------------------------
/src/thrift/TSCons.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | from os import path
21 | from SCons.Builder import Builder
22 |
23 | def scons_env(env, add=''):
24 | opath = path.dirname(path.abspath('$TARGET'))
25 | lstr = 'thrift --gen cpp -o ' + opath + ' ' + add + ' $SOURCE'
26 | cppbuild = Builder(action = lstr)
27 | env.Append(BUILDERS = {'ThriftCpp' : cppbuild})
28 |
29 | def gen_cpp(env, dir, file):
30 | scons_env(env)
31 | suffixes = ['_types.h', '_types.cpp']
32 | targets = map(lambda s: 'gen-cpp/' + file + s, suffixes)
33 | return env.ThriftCpp(targets, dir+file+'.thrift')
34 |
--------------------------------------------------------------------------------
/src/thrift/TSerialization.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | from protocol import TBinaryProtocol
21 | from transport import TTransport
22 |
23 | def serialize(thrift_object, protocol_factory = TBinaryProtocol.TBinaryProtocolFactory()):
24 | transport = TTransport.TMemoryBuffer()
25 | protocol = protocol_factory.getProtocol(transport)
26 | thrift_object.write(protocol)
27 | return transport.getvalue()
28 |
29 | def deserialize(base, buf, protocol_factory = TBinaryProtocol.TBinaryProtocolFactory()):
30 | transport = TTransport.TMemoryBuffer(buf)
31 | protocol = protocol_factory.getProtocol(transport)
32 | base.read(protocol)
33 | return base
34 |
35 |
--------------------------------------------------------------------------------
/src/thrift/server/THttpServer.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | import BaseHTTPServer
21 |
22 | from thrift.server import TServer
23 | from thrift.transport import TTransport
24 |
25 | class THttpServer(TServer.TServer):
26 | """A simple HTTP-based Thrift server
27 |
28 | This class is not very performant, but it is useful (for example) for
29 | acting as a mock version of an Apache-based PHP Thrift endpoint."""
30 |
31 | def __init__(self, processor, server_address,
32 | inputProtocolFactory, outputProtocolFactory = None):
33 | """Set up protocol factories and HTTP server.
34 |
35 | See BaseHTTPServer for server_address.
36 | See TServer for protocol factories."""
37 |
38 | if outputProtocolFactory is None:
39 | outputProtocolFactory = inputProtocolFactory
40 |
41 | TServer.TServer.__init__(self, processor, None, None, None,
42 | inputProtocolFactory, outputProtocolFactory)
43 |
44 | thttpserver = self
45 |
46 | class RequestHander(BaseHTTPServer.BaseHTTPRequestHandler):
47 | def do_POST(self):
48 | # Don't care about the request path.
49 | self.send_response(200)
50 | self.send_header("content-type", "application/x-thrift")
51 | self.end_headers()
52 |
53 | itrans = TTransport.TFileObjectTransport(self.rfile)
54 | otrans = TTransport.TFileObjectTransport(self.wfile)
55 | iprot = thttpserver.inputProtocolFactory.getProtocol(itrans)
56 | oprot = thttpserver.outputProtocolFactory.getProtocol(otrans)
57 | thttpserver.processor.process(iprot, oprot)
58 | otrans.flush()
59 |
60 | self.httpd = BaseHTTPServer.HTTPServer(server_address, RequestHander)
61 |
62 | def serve(self):
63 | self.httpd.serve_forever()
64 |
--------------------------------------------------------------------------------
/src/evernote/edam/userstore/UserStore-remote:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Autogenerated by Thrift
4 | #
5 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
6 | #
7 |
8 | import sys
9 | import pprint
10 | from urlparse import urlparse
11 | from thrift.transport import TTransport
12 | from thrift.transport import TSocket
13 | from thrift.transport import THttpClient
14 | from thrift.protocol import TBinaryProtocol
15 |
16 | import UserStore
17 | from ttypes import *
18 |
19 | if len(sys.argv) <= 1 or sys.argv[1] == '--help':
20 | print ''
21 | print 'Usage: ' + sys.argv[0] + ' [-h host:port] [-u url] [-f[ramed]] function [arg1 [arg2...]]'
22 | print ''
23 | print 'Functions:'
24 | print ' bool checkVersion(string clientName, i16 edamVersionMajor, i16 edamVersionMinor)'
25 | print ' AuthenticationResult authenticate(string username, string password, string consumerKey, string consumerSecret)'
26 | print ' AuthenticationResult refreshAuthentication(string authenticationToken)'
27 | print ' User getUser(string authenticationToken)'
28 | print ' PublicUserInfo getPublicUserInfo(string username)'
29 | print ' PremiumInfo getPremiumInfo(string authenticationToken)'
30 | print ''
31 | sys.exit(0)
32 |
33 | pp = pprint.PrettyPrinter(indent = 2)
34 | host = 'localhost'
35 | port = 9090
36 | uri = ''
37 | framed = False
38 | http = False
39 | argi = 1
40 |
41 | if sys.argv[argi] == '-h':
42 | parts = sys.argv[argi+1].split(':')
43 | host = parts[0]
44 | port = int(parts[1])
45 | argi += 2
46 |
47 | if sys.argv[argi] == '-u':
48 | url = urlparse(sys.argv[argi+1])
49 | parts = url[1].split(':')
50 | host = parts[0]
51 | if len(parts) > 1:
52 | port = int(parts[1])
53 | else:
54 | port = 80
55 | uri = url[2]
56 | http = True
57 | argi += 2
58 |
59 | if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':
60 | framed = True
61 | argi += 1
62 |
63 | cmd = sys.argv[argi]
64 | args = sys.argv[argi+1:]
65 |
66 | if http:
67 | transport = THttpClient.THttpClient(host, port, uri)
68 | else:
69 | socket = TSocket.TSocket(host, port)
70 | if framed:
71 | transport = TTransport.TFramedTransport(socket)
72 | else:
73 | transport = TTransport.TBufferedTransport(socket)
74 | protocol = TBinaryProtocol.TBinaryProtocol(transport)
75 | client = UserStore.Client(protocol)
76 | transport.open()
77 |
78 | if cmd == 'checkVersion':
79 | if len(args) != 3:
80 | print 'checkVersion requires 3 args'
81 | sys.exit(1)
82 | pp.pprint(client.checkVersion(args[0],eval(args[1]),eval(args[2]),))
83 |
84 | elif cmd == 'authenticate':
85 | if len(args) != 4:
86 | print 'authenticate requires 4 args'
87 | sys.exit(1)
88 | pp.pprint(client.authenticate(args[0],args[1],args[2],args[3],))
89 |
90 | elif cmd == 'refreshAuthentication':
91 | if len(args) != 1:
92 | print 'refreshAuthentication requires 1 args'
93 | sys.exit(1)
94 | pp.pprint(client.refreshAuthentication(args[0],))
95 |
96 | elif cmd == 'getUser':
97 | if len(args) != 1:
98 | print 'getUser requires 1 args'
99 | sys.exit(1)
100 | pp.pprint(client.getUser(args[0],))
101 |
102 | elif cmd == 'getPublicUserInfo':
103 | if len(args) != 1:
104 | print 'getPublicUserInfo requires 1 args'
105 | sys.exit(1)
106 | pp.pprint(client.getPublicUserInfo(args[0],))
107 |
108 | elif cmd == 'getPremiumInfo':
109 | if len(args) != 1:
110 | print 'getPremiumInfo requires 1 args'
111 | sys.exit(1)
112 | pp.pprint(client.getPremiumInfo(args[0],))
113 |
114 | transport.close()
115 |
--------------------------------------------------------------------------------
/src/thrift/Thrift.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | import sys
21 |
22 | class TType:
23 | STOP = 0
24 | VOID = 1
25 | BOOL = 2
26 | BYTE = 3
27 | I08 = 3
28 | DOUBLE = 4
29 | I16 = 6
30 | I32 = 8
31 | I64 = 10
32 | STRING = 11
33 | UTF7 = 11
34 | STRUCT = 12
35 | MAP = 13
36 | SET = 14
37 | LIST = 15
38 | UTF8 = 16
39 | UTF16 = 17
40 |
41 | class TMessageType:
42 | CALL = 1
43 | REPLY = 2
44 | EXCEPTION = 3
45 | ONEWAY = 4
46 |
47 | class TProcessor:
48 |
49 | """Base class for procsessor, which works on two streams."""
50 |
51 | def process(iprot, oprot):
52 | pass
53 |
54 | class TException(Exception):
55 |
56 | """Base class for all thrift exceptions."""
57 |
58 | # BaseException.message is deprecated in Python v[2.6,3.0)
59 | if (2,6,0) <= sys.version_info < (3,0):
60 | def _get_message(self):
61 | return self._message
62 | def _set_message(self, message):
63 | self._message = message
64 | message = property(_get_message, _set_message)
65 |
66 | def __init__(self, message=None):
67 | Exception.__init__(self, message)
68 | self.message = message
69 |
70 | class TApplicationException(TException):
71 |
72 | """Application level thrift exceptions."""
73 |
74 | UNKNOWN = 0
75 | UNKNOWN_METHOD = 1
76 | INVALID_MESSAGE_TYPE = 2
77 | WRONG_METHOD_NAME = 3
78 | BAD_SEQUENCE_ID = 4
79 | MISSING_RESULT = 5
80 |
81 | def __init__(self, type=UNKNOWN, message=None):
82 | TException.__init__(self, message)
83 | self.type = type
84 |
85 | def __str__(self):
86 | if self.message:
87 | return self.message
88 | elif self.type == UNKNOWN_METHOD:
89 | return 'Unknown method'
90 | elif self.type == INVALID_MESSAGE_TYPE:
91 | return 'Invalid message type'
92 | elif self.type == WRONG_METHOD_NAME:
93 | return 'Wrong method name'
94 | elif self.type == BAD_SEQUENCE_ID:
95 | return 'Bad sequence ID'
96 | elif self.type == MISSING_RESULT:
97 | return 'Missing result'
98 | else:
99 | return 'Default (unknown) TApplicationException'
100 |
101 | def read(self, iprot):
102 | iprot.readStructBegin()
103 | while True:
104 | (fname, ftype, fid) = iprot.readFieldBegin()
105 | if ftype == TType.STOP:
106 | break
107 | if fid == 1:
108 | if ftype == TType.STRING:
109 | self.message = iprot.readString();
110 | else:
111 | iprot.skip(ftype)
112 | elif fid == 2:
113 | if ftype == TType.I32:
114 | self.type = iprot.readI32();
115 | else:
116 | iprot.skip(ftype)
117 | else:
118 | iprot.skip(ftype)
119 | iprot.readFieldEnd()
120 | iprot.readStructEnd()
121 |
122 | def write(self, oprot):
123 | oprot.writeStructBegin('TApplicationException')
124 | if self.message != None:
125 | oprot.writeFieldBegin('message', TType.STRING, 1)
126 | oprot.writeString(self.message)
127 | oprot.writeFieldEnd()
128 | if self.type != None:
129 | oprot.writeFieldBegin('type', TType.I32, 2)
130 | oprot.writeI32(self.type)
131 | oprot.writeFieldEnd()
132 | oprot.writeFieldStop()
133 | oprot.writeStructEnd()
134 |
--------------------------------------------------------------------------------
/src/thrift/transport/THttpClient.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | from TTransport import *
21 | from cStringIO import StringIO
22 |
23 | import urlparse
24 | import httplib
25 | import warnings
26 | import socket
27 |
28 | class THttpClient(TTransportBase):
29 |
30 | """Http implementation of TTransport base."""
31 |
32 | def __init__(self, uri_or_host, port=None, path=None):
33 | """THttpClient supports two different types constructor parameters.
34 |
35 | THttpClient(host, port, path) - deprecated
36 | THttpClient(uri)
37 |
38 | Only the second supports https."""
39 |
40 | if port is not None:
41 | warnings.warn("Please use the THttpClient('http://host:port/path') syntax", DeprecationWarning, stacklevel=2)
42 | self.host = uri_or_host
43 | self.port = port
44 | assert path
45 | self.path = path
46 | self.scheme = 'http'
47 | else:
48 | parsed = urlparse.urlparse(uri_or_host)
49 | self.scheme = parsed.scheme
50 | assert self.scheme in ('http', 'https')
51 | if self.scheme == 'http':
52 | self.port = parsed.port or httplib.HTTP_PORT
53 | elif self.scheme == 'https':
54 | self.port = parsed.port or httplib.HTTPS_PORT
55 | self.host = parsed.hostname
56 | self.path = parsed.path
57 | self.__wbuf = StringIO()
58 | self.__http = None
59 | self.__timeout = None
60 |
61 | def open(self):
62 | if self.scheme == 'http':
63 | self.__http = httplib.HTTP(self.host, self.port)
64 | else:
65 | self.__http = httplib.HTTPS(self.host, self.port)
66 |
67 | def close(self):
68 | self.__http.close()
69 | self.__http = None
70 |
71 | def isOpen(self):
72 | return self.__http != None
73 |
74 | def setTimeout(self, ms):
75 | if not hasattr(socket, 'getdefaulttimeout'):
76 | raise NotImplementedError
77 |
78 | if ms is None:
79 | self.__timeout = None
80 | else:
81 | self.__timeout = ms/1000.0
82 |
83 | def read(self, sz):
84 | return self.__http.file.read(sz)
85 |
86 | def write(self, buf):
87 | self.__wbuf.write(buf)
88 |
89 | def __withTimeout(f):
90 | def _f(*args, **kwargs):
91 | orig_timeout = socket.getdefaulttimeout()
92 | socket.setdefaulttimeout(args[0].__timeout)
93 | result = f(*args, **kwargs)
94 | socket.setdefaulttimeout(orig_timeout)
95 | return result
96 | return _f
97 |
98 | def flush(self):
99 | if self.isOpen():
100 | self.close()
101 | self.open();
102 |
103 | # Pull data out of buffer
104 | data = self.__wbuf.getvalue()
105 | self.__wbuf = StringIO()
106 |
107 | # HTTP request
108 | self.__http.putrequest('POST', self.path)
109 |
110 | # Write headers
111 | self.__http.putheader('Host', self.host)
112 | self.__http.putheader('Content-Type', 'application/x-thrift')
113 | self.__http.putheader('Content-Length', str(len(data)))
114 | self.__http.endheaders()
115 |
116 | # Write payload
117 | self.__http.send(data)
118 |
119 | # Get reply to flush the request
120 | self.code, self.message, self.headers = self.__http.getreply()
121 |
122 | # Decorate if we know how to timeout
123 | if hasattr(socket, 'getdefaulttimeout'):
124 | flush = __withTimeout(flush)
125 |
--------------------------------------------------------------------------------
/src/thrift/protocol/TProtocol.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | from thrift.Thrift import *
21 |
22 | class TProtocolException(TException):
23 |
24 | """Custom Protocol Exception class"""
25 |
26 | UNKNOWN = 0
27 | INVALID_DATA = 1
28 | NEGATIVE_SIZE = 2
29 | SIZE_LIMIT = 3
30 | BAD_VERSION = 4
31 |
32 | def __init__(self, type=UNKNOWN, message=None):
33 | TException.__init__(self, message)
34 | self.type = type
35 |
36 | class TProtocolBase:
37 |
38 | """Base class for Thrift protocol driver."""
39 |
40 | def __init__(self, trans):
41 | self.trans = trans
42 |
43 | def writeMessageBegin(self, name, type, seqid):
44 | pass
45 |
46 | def writeMessageEnd(self):
47 | pass
48 |
49 | def writeStructBegin(self, name):
50 | pass
51 |
52 | def writeStructEnd(self):
53 | pass
54 |
55 | def writeFieldBegin(self, name, type, id):
56 | pass
57 |
58 | def writeFieldEnd(self):
59 | pass
60 |
61 | def writeFieldStop(self):
62 | pass
63 |
64 | def writeMapBegin(self, ktype, vtype, size):
65 | pass
66 |
67 | def writeMapEnd(self):
68 | pass
69 |
70 | def writeListBegin(self, etype, size):
71 | pass
72 |
73 | def writeListEnd(self):
74 | pass
75 |
76 | def writeSetBegin(self, etype, size):
77 | pass
78 |
79 | def writeSetEnd(self):
80 | pass
81 |
82 | def writeBool(self, bool):
83 | pass
84 |
85 | def writeByte(self, byte):
86 | pass
87 |
88 | def writeI16(self, i16):
89 | pass
90 |
91 | def writeI32(self, i32):
92 | pass
93 |
94 | def writeI64(self, i64):
95 | pass
96 |
97 | def writeDouble(self, dub):
98 | pass
99 |
100 | def writeString(self, str):
101 | pass
102 |
103 | def readMessageBegin(self):
104 | pass
105 |
106 | def readMessageEnd(self):
107 | pass
108 |
109 | def readStructBegin(self):
110 | pass
111 |
112 | def readStructEnd(self):
113 | pass
114 |
115 | def readFieldBegin(self):
116 | pass
117 |
118 | def readFieldEnd(self):
119 | pass
120 |
121 | def readMapBegin(self):
122 | pass
123 |
124 | def readMapEnd(self):
125 | pass
126 |
127 | def readListBegin(self):
128 | pass
129 |
130 | def readListEnd(self):
131 | pass
132 |
133 | def readSetBegin(self):
134 | pass
135 |
136 | def readSetEnd(self):
137 | pass
138 |
139 | def readBool(self):
140 | pass
141 |
142 | def readByte(self):
143 | pass
144 |
145 | def readI16(self):
146 | pass
147 |
148 | def readI32(self):
149 | pass
150 |
151 | def readI64(self):
152 | pass
153 |
154 | def readDouble(self):
155 | pass
156 |
157 | def readString(self):
158 | pass
159 |
160 | def skip(self, type):
161 | if type == TType.STOP:
162 | return
163 | elif type == TType.BOOL:
164 | self.readBool()
165 | elif type == TType.BYTE:
166 | self.readByte()
167 | elif type == TType.I16:
168 | self.readI16()
169 | elif type == TType.I32:
170 | self.readI32()
171 | elif type == TType.I64:
172 | self.readI64()
173 | elif type == TType.DOUBLE:
174 | self.readDouble()
175 | elif type == TType.STRING:
176 | self.readString()
177 | elif type == TType.STRUCT:
178 | name = self.readStructBegin()
179 | while True:
180 | (name, type, id) = self.readFieldBegin()
181 | if type == TType.STOP:
182 | break
183 | self.skip(type)
184 | self.readFieldEnd()
185 | self.readStructEnd()
186 | elif type == TType.MAP:
187 | (ktype, vtype, size) = self.readMapBegin()
188 | for i in range(size):
189 | self.skip(ktype)
190 | self.skip(vtype)
191 | self.readMapEnd()
192 | elif type == TType.SET:
193 | (etype, size) = self.readSetBegin()
194 | for i in range(size):
195 | self.skip(etype)
196 | self.readSetEnd()
197 | elif type == TType.LIST:
198 | (etype, size) = self.readListBegin()
199 | for i in range(size):
200 | self.skip(etype)
201 | self.readListEnd()
202 |
203 | class TProtocolFactory:
204 | def getProtocol(self, trans):
205 | pass
206 |
--------------------------------------------------------------------------------
/src/thrift/transport/TSocket.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | from TTransport import *
21 | import os
22 | import errno
23 | import socket
24 |
25 | class TSocketBase(TTransportBase):
26 | def _resolveAddr(self):
27 | if self._unix_socket is not None:
28 | return [(socket.AF_UNIX, socket.SOCK_STREAM, None, None, self._unix_socket)]
29 | else:
30 | return socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE | socket.AI_ADDRCONFIG)
31 |
32 | def close(self):
33 | if self.handle:
34 | self.handle.close()
35 | self.handle = None
36 |
37 | class TSocket(TSocketBase):
38 | """Socket implementation of TTransport base."""
39 |
40 | def __init__(self, host='localhost', port=9090, unix_socket=None):
41 | """Initialize a TSocket
42 |
43 | @param host(str) The host to connect to.
44 | @param port(int) The (TCP) port to connect to.
45 | @param unix_socket(str) The filename of a unix socket to connect to.
46 | (host and port will be ignored.)
47 | """
48 |
49 | self.host = host
50 | self.port = port
51 | self.handle = None
52 | self._unix_socket = unix_socket
53 | self._timeout = None
54 |
55 | def setHandle(self, h):
56 | self.handle = h
57 |
58 | def isOpen(self):
59 | return self.handle != None
60 |
61 | def setTimeout(self, ms):
62 | if ms is None:
63 | self._timeout = None
64 | else:
65 | self._timeout = ms/1000.0
66 |
67 | if (self.handle != None):
68 | self.handle.settimeout(self._timeout)
69 |
70 | def open(self):
71 | try:
72 | res0 = self._resolveAddr()
73 | for res in res0:
74 | self.handle = socket.socket(res[0], res[1])
75 | self.handle.settimeout(self._timeout)
76 | try:
77 | self.handle.connect(res[4])
78 | except socket.error, e:
79 | if res is not res0[-1]:
80 | continue
81 | else:
82 | raise e
83 | break
84 | except socket.error, e:
85 | if self._unix_socket:
86 | message = 'Could not connect to socket %s' % self._unix_socket
87 | else:
88 | message = 'Could not connect to %s:%d' % (self.host, self.port)
89 | raise TTransportException(type=TTransportException.NOT_OPEN, message=message)
90 |
91 | def read(self, sz):
92 | buff = self.handle.recv(sz)
93 | if len(buff) == 0:
94 | raise TTransportException(type=TTransportException.END_OF_FILE, message='TSocket read 0 bytes')
95 | return buff
96 |
97 | def write(self, buff):
98 | if not self.handle:
99 | raise TTransportException(type=TTransportException.NOT_OPEN, message='Transport not open')
100 | sent = 0
101 | have = len(buff)
102 | while sent < have:
103 | plus = self.handle.send(buff)
104 | if plus == 0:
105 | raise TTransportException(type=TTransportException.END_OF_FILE, message='TSocket sent 0 bytes')
106 | sent += plus
107 | buff = buff[plus:]
108 |
109 | def flush(self):
110 | pass
111 |
112 | class TServerSocket(TSocketBase, TServerTransportBase):
113 | """Socket implementation of TServerTransport base."""
114 |
115 | def __init__(self, port=9090, unix_socket=None):
116 | self.host = None
117 | self.port = port
118 | self._unix_socket = unix_socket
119 | self.handle = None
120 |
121 | def listen(self):
122 | res0 = self._resolveAddr()
123 | for res in res0:
124 | if res[0] is socket.AF_INET6 or res is res0[-1]:
125 | break
126 |
127 | # We need remove the old unix socket if the file exists and
128 | # nobody is listening on it.
129 | if self._unix_socket:
130 | tmp = socket.socket(res[0], res[1])
131 | try:
132 | tmp.connect(res[4])
133 | except socket.error, err:
134 | eno, message = err.args
135 | if eno == errno.ECONNREFUSED:
136 | os.unlink(res[4])
137 |
138 | self.handle = socket.socket(res[0], res[1])
139 | self.handle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
140 | if hasattr(self.handle, 'set_timeout'):
141 | self.handle.set_timeout(None)
142 | self.handle.bind(res[4])
143 | self.handle.listen(128)
144 |
145 | def accept(self):
146 | client, addr = self.handle.accept()
147 | result = TSocket()
148 | result.setHandle(client)
149 | return result
150 |
--------------------------------------------------------------------------------
/src/evernote/edam/limits/constants.py:
--------------------------------------------------------------------------------
1 | #
2 | # Autogenerated by Thrift
3 | #
4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5 | #
6 |
7 | from thrift.Thrift import *
8 | from ttypes import *
9 |
10 | EDAM_ATTRIBUTE_LEN_MIN = 1
11 |
12 | EDAM_ATTRIBUTE_LEN_MAX = 4096
13 |
14 | EDAM_ATTRIBUTE_REGEX = "^[^\\p{Cc}\\p{Zl}\\p{Zp}]{1,4096}$"
15 |
16 | EDAM_ATTRIBUTE_LIST_MAX = 100
17 |
18 | EDAM_ATTRIBUTE_MAP_MAX = 100
19 |
20 | EDAM_GUID_LEN_MIN = 36
21 |
22 | EDAM_GUID_LEN_MAX = 36
23 |
24 | EDAM_GUID_REGEX = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
25 |
26 | EDAM_EMAIL_LEN_MIN = 6
27 |
28 | EDAM_EMAIL_LEN_MAX = 255
29 |
30 | EDAM_EMAIL_LOCAL_REGEX = "^[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(\\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*$"
31 |
32 | EDAM_EMAIL_DOMAIN_REGEX = "^[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*\\.([A-Za-z]{2,})$"
33 |
34 | EDAM_EMAIL_REGEX = "^[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(\\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*\\.([A-Za-z]{2,})$"
35 |
36 | EDAM_TIMEZONE_LEN_MIN = 1
37 |
38 | EDAM_TIMEZONE_LEN_MAX = 32
39 |
40 | EDAM_TIMEZONE_REGEX = "^([A-Za-z_-]+(/[A-Za-z_-]+)*)|(GMT(-|\\+)[0-9]{1,2}(:[0-9]{2})?)$"
41 |
42 | EDAM_MIME_LEN_MIN = 3
43 |
44 | EDAM_MIME_LEN_MAX = 255
45 |
46 | EDAM_MIME_REGEX = "^[A-Za-z]+/[A-Za-z0-9._+-]+$"
47 |
48 | EDAM_MIME_TYPE_GIF = "image/gif"
49 |
50 | EDAM_MIME_TYPE_JPEG = "image/jpeg"
51 |
52 | EDAM_MIME_TYPE_PNG = "image/png"
53 |
54 | EDAM_MIME_TYPE_WAV = "audio/wav"
55 |
56 | EDAM_MIME_TYPE_MP3 = "audio/mpeg"
57 |
58 | EDAM_MIME_TYPE_AMR = "audio/amr"
59 |
60 | EDAM_MIME_TYPE_MP4_VIDEO = "video/mp4"
61 |
62 | EDAM_MIME_TYPE_INK = "application/vnd.evernote.ink"
63 |
64 | EDAM_MIME_TYPE_PDF = "application/pdf"
65 |
66 | EDAM_MIME_TYPE_DEFAULT = "application/octet-stream"
67 |
68 | EDAM_MIME_TYPES = set([
69 | "image/gif",
70 | "image/jpeg",
71 | "image/png",
72 | "audio/wav",
73 | "audio/mpeg",
74 | "audio/amr",
75 | "application/vnd.evernote.ink",
76 | "application/pdf",
77 | "video/mp4",
78 | ])
79 |
80 | EDAM_COMMERCE_SERVICE_GOOGLE = "Google"
81 |
82 | EDAM_COMMERCE_SERVICE_PAYPAL = "Paypal"
83 |
84 | EDAM_COMMERCE_SERVICE_GIFT = "Gift"
85 |
86 | EDAM_COMMERCE_SERVICE_TRIALPAY = "TrialPay"
87 |
88 | EDAM_COMMERCE_SERVICE_TRIAL = "Trial"
89 |
90 | EDAM_COMMERCE_SERVICE_GROUP = "Group"
91 |
92 | EDAM_COMMERCE_SERVICE_CYBERSOURCE = "CYBERSRC"
93 |
94 | EDAM_COMMERCE_DEFAULT_CURRENCY_COUNTRY_CODE = "USD"
95 |
96 | EDAM_SEARCH_QUERY_LEN_MIN = 0
97 |
98 | EDAM_SEARCH_QUERY_LEN_MAX = 1024
99 |
100 | EDAM_SEARCH_QUERY_REGEX = "^[^\\p{Cc}\\p{Zl}\\p{Zp}]{0,1024}$"
101 |
102 | EDAM_HASH_LEN = 16
103 |
104 | EDAM_USER_USERNAME_LEN_MIN = 1
105 |
106 | EDAM_USER_USERNAME_LEN_MAX = 64
107 |
108 | EDAM_USER_USERNAME_REGEX = "^[a-z0-9]([a-z0-9_-]{0,62}[a-z0-9])?$"
109 |
110 | EDAM_USER_NAME_LEN_MIN = 1
111 |
112 | EDAM_USER_NAME_LEN_MAX = 255
113 |
114 | EDAM_USER_NAME_REGEX = "^[^\\p{Cc}\\p{Zl}\\p{Zp}]{1,255}$"
115 |
116 | EDAM_TAG_NAME_LEN_MIN = 1
117 |
118 | EDAM_TAG_NAME_LEN_MAX = 100
119 |
120 | EDAM_TAG_NAME_REGEX = "^[^,\\p{Cc}\\p{Z}]([^,\\p{Cc}\\p{Zl}\\p{Zp}]{0,98}[^,\\p{Cc}\\p{Z}])?$"
121 |
122 | EDAM_NOTE_TITLE_LEN_MIN = 1
123 |
124 | EDAM_NOTE_TITLE_LEN_MAX = 255
125 |
126 | EDAM_NOTE_TITLE_REGEX = "^[^\\p{Cc}\\p{Z}]([^\\p{Cc}\\p{Zl}\\p{Zp}]{0,253}[^\\p{Cc}\\p{Z}])?$"
127 |
128 | EDAM_NOTE_CONTENT_LEN_MIN = 0
129 |
130 | EDAM_NOTE_CONTENT_LEN_MAX = 5242880
131 |
132 | EDAM_APPLICATIONDATA_NAME_LEN_MIN = 3
133 |
134 | EDAM_APPLICATIONDATA_NAME_LEN_MAX = 32
135 |
136 | EDAM_APPLICATIONDATA_VALUE_LEN_MIN = 0
137 |
138 | EDAM_APPLICATIONDATA_VALUE_LEN_MAX = 4092
139 |
140 | EDAM_APPLICATIONDATA_ENTRY_LEN_MAX = 4095
141 |
142 | EDAM_APPLICATIONDATA_NAME_REGEX = "^[A-Za-z0-9_.-]{3,32}$"
143 |
144 | EDAM_APPLICATIONDATA_VALUE_REGEX = "^[^\\p{Cc}]{0,4092}$"
145 |
146 | EDAM_NOTEBOOK_NAME_LEN_MIN = 1
147 |
148 | EDAM_NOTEBOOK_NAME_LEN_MAX = 100
149 |
150 | EDAM_NOTEBOOK_NAME_REGEX = "^[^\\p{Cc}\\p{Z}]([^\\p{Cc}\\p{Zl}\\p{Zp}]{0,98}[^\\p{Cc}\\p{Z}])?$"
151 |
152 | EDAM_NOTEBOOK_STACK_LEN_MIN = 1
153 |
154 | EDAM_NOTEBOOK_STACK_LEN_MAX = 100
155 |
156 | EDAM_NOTEBOOK_STACK_REGEX = "^[^\\p{Cc}\\p{Z}]([^\\p{Cc}\\p{Zl}\\p{Zp}]{0,98}[^\\p{Cc}\\p{Z}])?$"
157 |
158 | EDAM_PUBLISHING_URI_LEN_MIN = 1
159 |
160 | EDAM_PUBLISHING_URI_LEN_MAX = 255
161 |
162 | EDAM_PUBLISHING_URI_REGEX = "^[a-zA-Z0-9.~_+-]{1,255}$"
163 |
164 | EDAM_PUBLISHING_URI_PROHIBITED = set([
165 | "..",
166 | ])
167 |
168 | EDAM_PUBLISHING_DESCRIPTION_LEN_MIN = 1
169 |
170 | EDAM_PUBLISHING_DESCRIPTION_LEN_MAX = 200
171 |
172 | EDAM_PUBLISHING_DESCRIPTION_REGEX = "^[^\\p{Cc}\\p{Z}]([^\\p{Cc}\\p{Zl}\\p{Zp}]{0,198}[^\\p{Cc}\\p{Z}])?$"
173 |
174 | EDAM_SAVED_SEARCH_NAME_LEN_MIN = 1
175 |
176 | EDAM_SAVED_SEARCH_NAME_LEN_MAX = 100
177 |
178 | EDAM_SAVED_SEARCH_NAME_REGEX = "^[^\\p{Cc}\\p{Z}]([^\\p{Cc}\\p{Zl}\\p{Zp}]{0,98}[^\\p{Cc}\\p{Z}])?$"
179 |
180 | EDAM_USER_PASSWORD_LEN_MIN = 6
181 |
182 | EDAM_USER_PASSWORD_LEN_MAX = 64
183 |
184 | EDAM_USER_PASSWORD_REGEX = "^[A-Za-z0-9!#$%&'()*+,./:;<=>?@^_`{|}~\\[\\]\\\\-]{6,64}$"
185 |
186 | EDAM_NOTE_TAGS_MAX = 100
187 |
188 | EDAM_NOTE_RESOURCES_MAX = 1000
189 |
190 | EDAM_USER_TAGS_MAX = 100000
191 |
192 | EDAM_USER_SAVED_SEARCHES_MAX = 100
193 |
194 | EDAM_USER_NOTES_MAX = 100000
195 |
196 | EDAM_USER_NOTEBOOKS_MAX = 250
197 |
198 | EDAM_USER_RECENT_MAILED_ADDRESSES_MAX = 10
199 |
200 | EDAM_USER_MAIL_LIMIT_DAILY_FREE = 50
201 |
202 | EDAM_USER_MAIL_LIMIT_DAILY_PREMIUM = 200
203 |
204 | EDAM_USER_UPLOAD_LIMIT_FREE = 62914560
205 |
206 | EDAM_USER_UPLOAD_LIMIT_PREMIUM = 1073741824
207 |
208 | EDAM_NOTE_SIZE_MAX_FREE = 26214400
209 |
210 | EDAM_NOTE_SIZE_MAX_PREMIUM = 52428800
211 |
212 | EDAM_RESOURCE_SIZE_MAX_FREE = 26214400
213 |
214 | EDAM_RESOURCE_SIZE_MAX_PREMIUM = 52428800
215 |
216 | EDAM_USER_LINKED_NOTEBOOK_MAX = 100
217 |
218 | EDAM_NOTEBOOK_SHARED_NOTEBOOK_MAX = 250
219 |
220 | EDAM_NOTE_CONTENT_CLASS_LEN_MIN = 3
221 |
222 | EDAM_NOTE_CONTENT_CLASS_LEN_MAX = 32
223 |
224 | EDAM_HELLO_APP_CONTENT_CLASS_PREFIX = "evernote.hello."
225 |
226 | EDAM_FOOD_APP_CONTENT_CLASS_PREFIX = "evernote.food."
227 |
228 | EDAM_NOTE_CONTENT_CLASS_REGEX = "^[A-Za-z0-9_.-]{3,32}$"
229 |
230 | EDAM_CONTENT_CLASS_HELLO_ENCOUNTER = "evernote.hello.encounter"
231 |
232 | EDAM_CONTENT_CLASS_HELLO_PROFILE = "evernote.hello.profile"
233 |
234 | EDAM_CONTENT_CLASS_FOOD_MEAL = "evernote.food.meal"
235 |
236 |
--------------------------------------------------------------------------------
/src/thrift/transport/TTwisted.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 | from zope.interface import implements, Interface, Attribute
20 | from twisted.internet.protocol import Protocol, ServerFactory, ClientFactory, \
21 | connectionDone
22 | from twisted.internet import defer
23 | from twisted.protocols import basic
24 | from twisted.python import log
25 | from twisted.web import server, resource, http
26 |
27 | from thrift.transport import TTransport
28 | from cStringIO import StringIO
29 |
30 |
31 | class TMessageSenderTransport(TTransport.TTransportBase):
32 |
33 | def __init__(self):
34 | self.__wbuf = StringIO()
35 |
36 | def write(self, buf):
37 | self.__wbuf.write(buf)
38 |
39 | def flush(self):
40 | msg = self.__wbuf.getvalue()
41 | self.__wbuf = StringIO()
42 | self.sendMessage(msg)
43 |
44 | def sendMessage(self, message):
45 | raise NotImplementedError
46 |
47 |
48 | class TCallbackTransport(TMessageSenderTransport):
49 |
50 | def __init__(self, func):
51 | TMessageSenderTransport.__init__(self)
52 | self.func = func
53 |
54 | def sendMessage(self, message):
55 | self.func(message)
56 |
57 |
58 | class ThriftClientProtocol(basic.Int32StringReceiver):
59 |
60 | MAX_LENGTH = 2 ** 31 - 1
61 |
62 | def __init__(self, client_class, iprot_factory, oprot_factory=None):
63 | self._client_class = client_class
64 | self._iprot_factory = iprot_factory
65 | if oprot_factory is None:
66 | self._oprot_factory = iprot_factory
67 | else:
68 | self._oprot_factory = oprot_factory
69 |
70 | self.recv_map = {}
71 | self.started = defer.Deferred()
72 |
73 | def dispatch(self, msg):
74 | self.sendString(msg)
75 |
76 | def connectionMade(self):
77 | tmo = TCallbackTransport(self.dispatch)
78 | self.client = self._client_class(tmo, self._oprot_factory)
79 | self.started.callback(self.client)
80 |
81 | def connectionLost(self, reason=connectionDone):
82 | for k,v in self.client._reqs.iteritems():
83 | tex = TTransport.TTransportException(
84 | type=TTransport.TTransportException.END_OF_FILE,
85 | message='Connection closed')
86 | v.errback(tex)
87 |
88 | def stringReceived(self, frame):
89 | tr = TTransport.TMemoryBuffer(frame)
90 | iprot = self._iprot_factory.getProtocol(tr)
91 | (fname, mtype, rseqid) = iprot.readMessageBegin()
92 |
93 | try:
94 | method = self.recv_map[fname]
95 | except KeyError:
96 | method = getattr(self.client, 'recv_' + fname)
97 | self.recv_map[fname] = method
98 |
99 | method(iprot, mtype, rseqid)
100 |
101 |
102 | class ThriftServerProtocol(basic.Int32StringReceiver):
103 |
104 | MAX_LENGTH = 2 ** 31 - 1
105 |
106 | def dispatch(self, msg):
107 | self.sendString(msg)
108 |
109 | def processError(self, error):
110 | self.transport.loseConnection()
111 |
112 | def processOk(self, _, tmo):
113 | msg = tmo.getvalue()
114 |
115 | if len(msg) > 0:
116 | self.dispatch(msg)
117 |
118 | def stringReceived(self, frame):
119 | tmi = TTransport.TMemoryBuffer(frame)
120 | tmo = TTransport.TMemoryBuffer()
121 |
122 | iprot = self.factory.iprot_factory.getProtocol(tmi)
123 | oprot = self.factory.oprot_factory.getProtocol(tmo)
124 |
125 | d = self.factory.processor.process(iprot, oprot)
126 | d.addCallbacks(self.processOk, self.processError,
127 | callbackArgs=(tmo,))
128 |
129 |
130 | class IThriftServerFactory(Interface):
131 |
132 | processor = Attribute("Thrift processor")
133 |
134 | iprot_factory = Attribute("Input protocol factory")
135 |
136 | oprot_factory = Attribute("Output protocol factory")
137 |
138 |
139 | class IThriftClientFactory(Interface):
140 |
141 | client_class = Attribute("Thrift client class")
142 |
143 | iprot_factory = Attribute("Input protocol factory")
144 |
145 | oprot_factory = Attribute("Output protocol factory")
146 |
147 |
148 | class ThriftServerFactory(ServerFactory):
149 |
150 | implements(IThriftServerFactory)
151 |
152 | protocol = ThriftServerProtocol
153 |
154 | def __init__(self, processor, iprot_factory, oprot_factory=None):
155 | self.processor = processor
156 | self.iprot_factory = iprot_factory
157 | if oprot_factory is None:
158 | self.oprot_factory = iprot_factory
159 | else:
160 | self.oprot_factory = oprot_factory
161 |
162 |
163 | class ThriftClientFactory(ClientFactory):
164 |
165 | implements(IThriftClientFactory)
166 |
167 | protocol = ThriftClientProtocol
168 |
169 | def __init__(self, client_class, iprot_factory, oprot_factory=None):
170 | self.client_class = client_class
171 | self.iprot_factory = iprot_factory
172 | if oprot_factory is None:
173 | self.oprot_factory = iprot_factory
174 | else:
175 | self.oprot_factory = oprot_factory
176 |
177 | def buildProtocol(self, addr):
178 | p = self.protocol(self.client_class, self.iprot_factory,
179 | self.oprot_factory)
180 | p.factory = self
181 | return p
182 |
183 |
184 | class ThriftResource(resource.Resource):
185 |
186 | allowedMethods = ('POST',)
187 |
188 | def __init__(self, processor, inputProtocolFactory,
189 | outputProtocolFactory=None):
190 | resource.Resource.__init__(self)
191 | self.inputProtocolFactory = inputProtocolFactory
192 | if outputProtocolFactory is None:
193 | self.outputProtocolFactory = inputProtocolFactory
194 | else:
195 | self.outputProtocolFactory = outputProtocolFactory
196 | self.processor = processor
197 |
198 | def getChild(self, path, request):
199 | return self
200 |
201 | def _cbProcess(self, _, request, tmo):
202 | msg = tmo.getvalue()
203 | request.setResponseCode(http.OK)
204 | request.setHeader("content-type", "application/x-thrift")
205 | request.write(msg)
206 | request.finish()
207 |
208 | def render_POST(self, request):
209 | request.content.seek(0, 0)
210 | data = request.content.read()
211 | tmi = TTransport.TMemoryBuffer(data)
212 | tmo = TTransport.TMemoryBuffer()
213 |
214 | iprot = self.inputProtocolFactory.getProtocol(tmi)
215 | oprot = self.outputProtocolFactory.getProtocol(tmo)
216 |
217 | d = self.processor.process(iprot, oprot)
218 | d.addCallback(self._cbProcess, request, tmo)
219 | return server.NOT_DONE_YET
220 |
--------------------------------------------------------------------------------
/src/thrift/protocol/TBinaryProtocol.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | from TProtocol import *
21 | from struct import pack, unpack
22 |
23 | class TBinaryProtocol(TProtocolBase):
24 |
25 | """Binary implementation of the Thrift protocol driver."""
26 |
27 | # NastyHaxx. Python 2.4+ on 32-bit machines forces hex constants to be
28 | # positive, converting this into a long. If we hardcode the int value
29 | # instead it'll stay in 32 bit-land.
30 |
31 | # VERSION_MASK = 0xffff0000
32 | VERSION_MASK = -65536
33 |
34 | # VERSION_1 = 0x80010000
35 | VERSION_1 = -2147418112
36 |
37 | TYPE_MASK = 0x000000ff
38 |
39 | def __init__(self, trans, strictRead=False, strictWrite=True):
40 | TProtocolBase.__init__(self, trans)
41 | self.strictRead = strictRead
42 | self.strictWrite = strictWrite
43 |
44 | def writeMessageBegin(self, name, type, seqid):
45 | if self.strictWrite:
46 | self.writeI32(TBinaryProtocol.VERSION_1 | type)
47 | self.writeString(name)
48 | self.writeI32(seqid)
49 | else:
50 | self.writeString(name)
51 | self.writeByte(type)
52 | self.writeI32(seqid)
53 |
54 | def writeMessageEnd(self):
55 | pass
56 |
57 | def writeStructBegin(self, name):
58 | pass
59 |
60 | def writeStructEnd(self):
61 | pass
62 |
63 | def writeFieldBegin(self, name, type, id):
64 | self.writeByte(type)
65 | self.writeI16(id)
66 |
67 | def writeFieldEnd(self):
68 | pass
69 |
70 | def writeFieldStop(self):
71 | self.writeByte(TType.STOP);
72 |
73 | def writeMapBegin(self, ktype, vtype, size):
74 | self.writeByte(ktype)
75 | self.writeByte(vtype)
76 | self.writeI32(size)
77 |
78 | def writeMapEnd(self):
79 | pass
80 |
81 | def writeListBegin(self, etype, size):
82 | self.writeByte(etype)
83 | self.writeI32(size)
84 |
85 | def writeListEnd(self):
86 | pass
87 |
88 | def writeSetBegin(self, etype, size):
89 | self.writeByte(etype)
90 | self.writeI32(size)
91 |
92 | def writeSetEnd(self):
93 | pass
94 |
95 | def writeBool(self, bool):
96 | if bool:
97 | self.writeByte(1)
98 | else:
99 | self.writeByte(0)
100 |
101 | def writeByte(self, byte):
102 | buff = pack("!b", byte)
103 | self.trans.write(buff)
104 |
105 | def writeI16(self, i16):
106 | buff = pack("!h", i16)
107 | self.trans.write(buff)
108 |
109 | def writeI32(self, i32):
110 | buff = pack("!i", i32)
111 | self.trans.write(buff)
112 |
113 | def writeI64(self, i64):
114 | buff = pack("!q", i64)
115 | self.trans.write(buff)
116 |
117 | def writeDouble(self, dub):
118 | buff = pack("!d", dub)
119 | self.trans.write(buff)
120 |
121 | def writeString(self, str):
122 | self.writeI32(len(str))
123 | self.trans.write(str)
124 |
125 | def readMessageBegin(self):
126 | sz = self.readI32()
127 | if sz < 0:
128 | version = sz & TBinaryProtocol.VERSION_MASK
129 | if version != TBinaryProtocol.VERSION_1:
130 | raise TProtocolException(type=TProtocolException.BAD_VERSION, message='Bad version in readMessageBegin: %d' % (sz))
131 | type = sz & TBinaryProtocol.TYPE_MASK
132 | name = self.readString()
133 | seqid = self.readI32()
134 | else:
135 | if self.strictRead:
136 | raise TProtocolException(type=TProtocolException.BAD_VERSION, message='No protocol version header')
137 | name = self.trans.readAll(sz)
138 | type = self.readByte()
139 | seqid = self.readI32()
140 | return (name, type, seqid)
141 |
142 | def readMessageEnd(self):
143 | pass
144 |
145 | def readStructBegin(self):
146 | pass
147 |
148 | def readStructEnd(self):
149 | pass
150 |
151 | def readFieldBegin(self):
152 | type = self.readByte()
153 | if type == TType.STOP:
154 | return (None, type, 0)
155 | id = self.readI16()
156 | return (None, type, id)
157 |
158 | def readFieldEnd(self):
159 | pass
160 |
161 | def readMapBegin(self):
162 | ktype = self.readByte()
163 | vtype = self.readByte()
164 | size = self.readI32()
165 | return (ktype, vtype, size)
166 |
167 | def readMapEnd(self):
168 | pass
169 |
170 | def readListBegin(self):
171 | etype = self.readByte()
172 | size = self.readI32()
173 | return (etype, size)
174 |
175 | def readListEnd(self):
176 | pass
177 |
178 | def readSetBegin(self):
179 | etype = self.readByte()
180 | size = self.readI32()
181 | return (etype, size)
182 |
183 | def readSetEnd(self):
184 | pass
185 |
186 | def readBool(self):
187 | byte = self.readByte()
188 | if byte == 0:
189 | return False
190 | return True
191 |
192 | def readByte(self):
193 | buff = self.trans.readAll(1)
194 | val, = unpack('!b', buff)
195 | return val
196 |
197 | def readI16(self):
198 | buff = self.trans.readAll(2)
199 | val, = unpack('!h', buff)
200 | return val
201 |
202 | def readI32(self):
203 | buff = self.trans.readAll(4)
204 | val, = unpack('!i', buff)
205 | return val
206 |
207 | def readI64(self):
208 | buff = self.trans.readAll(8)
209 | val, = unpack('!q', buff)
210 | return val
211 |
212 | def readDouble(self):
213 | buff = self.trans.readAll(8)
214 | val, = unpack('!d', buff)
215 | return val
216 |
217 | def readString(self):
218 | len = self.readI32()
219 | str = self.trans.readAll(len)
220 | return str
221 |
222 |
223 | class TBinaryProtocolFactory:
224 | def __init__(self, strictRead=False, strictWrite=True):
225 | self.strictRead = strictRead
226 | self.strictWrite = strictWrite
227 |
228 | def getProtocol(self, trans):
229 | prot = TBinaryProtocol(trans, self.strictRead, self.strictWrite)
230 | return prot
231 |
232 |
233 | class TBinaryProtocolAccelerated(TBinaryProtocol):
234 |
235 | """C-Accelerated version of TBinaryProtocol.
236 |
237 | This class does not override any of TBinaryProtocol's methods,
238 | but the generated code recognizes it directly and will call into
239 | our C module to do the encoding, bypassing this object entirely.
240 | We inherit from TBinaryProtocol so that the normal TBinaryProtocol
241 | encoding can happen if the fastbinary module doesn't work for some
242 | reason. (TODO(dreiss): Make this happen sanely in more cases.)
243 |
244 | In order to take advantage of the C module, just use
245 | TBinaryProtocolAccelerated instead of TBinaryProtocol.
246 |
247 | NOTE: This code was contributed by an external developer.
248 | The internal Thrift team has reviewed and tested it,
249 | but we cannot guarantee that it is production-ready.
250 | Please feel free to report bugs and/or success stories
251 | to the public mailing list.
252 | """
253 |
254 | pass
255 |
256 |
257 | class TBinaryProtocolAcceleratedFactory:
258 | def getProtocol(self, trans):
259 | return TBinaryProtocolAccelerated(trans)
260 |
--------------------------------------------------------------------------------
/src/thrift/server/TServer.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | import logging
21 | import sys
22 | import os
23 | import traceback
24 | import threading
25 | import Queue
26 |
27 | from thrift.Thrift import TProcessor
28 | from thrift.transport import TTransport
29 | from thrift.protocol import TBinaryProtocol
30 |
31 | class TServer:
32 |
33 | """Base interface for a server, which must have a serve method."""
34 |
35 | """ 3 constructors for all servers:
36 | 1) (processor, serverTransport)
37 | 2) (processor, serverTransport, transportFactory, protocolFactory)
38 | 3) (processor, serverTransport,
39 | inputTransportFactory, outputTransportFactory,
40 | inputProtocolFactory, outputProtocolFactory)"""
41 | def __init__(self, *args):
42 | if (len(args) == 2):
43 | self.__initArgs__(args[0], args[1],
44 | TTransport.TTransportFactoryBase(),
45 | TTransport.TTransportFactoryBase(),
46 | TBinaryProtocol.TBinaryProtocolFactory(),
47 | TBinaryProtocol.TBinaryProtocolFactory())
48 | elif (len(args) == 4):
49 | self.__initArgs__(args[0], args[1], args[2], args[2], args[3], args[3])
50 | elif (len(args) == 6):
51 | self.__initArgs__(args[0], args[1], args[2], args[3], args[4], args[5])
52 |
53 | def __initArgs__(self, processor, serverTransport,
54 | inputTransportFactory, outputTransportFactory,
55 | inputProtocolFactory, outputProtocolFactory):
56 | self.processor = processor
57 | self.serverTransport = serverTransport
58 | self.inputTransportFactory = inputTransportFactory
59 | self.outputTransportFactory = outputTransportFactory
60 | self.inputProtocolFactory = inputProtocolFactory
61 | self.outputProtocolFactory = outputProtocolFactory
62 |
63 | def serve(self):
64 | pass
65 |
66 | class TSimpleServer(TServer):
67 |
68 | """Simple single-threaded server that just pumps around one transport."""
69 |
70 | def __init__(self, *args):
71 | TServer.__init__(self, *args)
72 |
73 | def serve(self):
74 | self.serverTransport.listen()
75 | while True:
76 | client = self.serverTransport.accept()
77 | itrans = self.inputTransportFactory.getTransport(client)
78 | otrans = self.outputTransportFactory.getTransport(client)
79 | iprot = self.inputProtocolFactory.getProtocol(itrans)
80 | oprot = self.outputProtocolFactory.getProtocol(otrans)
81 | try:
82 | while True:
83 | self.processor.process(iprot, oprot)
84 | except TTransport.TTransportException, tx:
85 | pass
86 | except Exception, x:
87 | logging.exception(x)
88 |
89 | itrans.close()
90 | otrans.close()
91 |
92 | class TThreadedServer(TServer):
93 |
94 | """Threaded server that spawns a new thread per each connection."""
95 |
96 | def __init__(self, *args):
97 | TServer.__init__(self, *args)
98 |
99 | def serve(self):
100 | self.serverTransport.listen()
101 | while True:
102 | try:
103 | client = self.serverTransport.accept()
104 | t = threading.Thread(target = self.handle, args=(client,))
105 | t.start()
106 | except KeyboardInterrupt:
107 | raise
108 | except Exception, x:
109 | logging.exception(x)
110 |
111 | def handle(self, client):
112 | itrans = self.inputTransportFactory.getTransport(client)
113 | otrans = self.outputTransportFactory.getTransport(client)
114 | iprot = self.inputProtocolFactory.getProtocol(itrans)
115 | oprot = self.outputProtocolFactory.getProtocol(otrans)
116 | try:
117 | while True:
118 | self.processor.process(iprot, oprot)
119 | except TTransport.TTransportException, tx:
120 | pass
121 | except Exception, x:
122 | logging.exception(x)
123 |
124 | itrans.close()
125 | otrans.close()
126 |
127 | class TThreadPoolServer(TServer):
128 |
129 | """Server with a fixed size pool of threads which service requests."""
130 |
131 | def __init__(self, *args):
132 | TServer.__init__(self, *args)
133 | self.clients = Queue.Queue()
134 | self.threads = 10
135 |
136 | def setNumThreads(self, num):
137 | """Set the number of worker threads that should be created"""
138 | self.threads = num
139 |
140 | def serveThread(self):
141 | """Loop around getting clients from the shared queue and process them."""
142 | while True:
143 | try:
144 | client = self.clients.get()
145 | self.serveClient(client)
146 | except Exception, x:
147 | logging.exception(x)
148 |
149 | def serveClient(self, client):
150 | """Process input/output from a client for as long as possible"""
151 | itrans = self.inputTransportFactory.getTransport(client)
152 | otrans = self.outputTransportFactory.getTransport(client)
153 | iprot = self.inputProtocolFactory.getProtocol(itrans)
154 | oprot = self.outputProtocolFactory.getProtocol(otrans)
155 | try:
156 | while True:
157 | self.processor.process(iprot, oprot)
158 | except TTransport.TTransportException, tx:
159 | pass
160 | except Exception, x:
161 | logging.exception(x)
162 |
163 | itrans.close()
164 | otrans.close()
165 |
166 | def serve(self):
167 | """Start a fixed number of worker threads and put client into a queue"""
168 | for i in range(self.threads):
169 | try:
170 | t = threading.Thread(target = self.serveThread)
171 | t.start()
172 | except Exception, x:
173 | logging.exception(x)
174 |
175 | # Pump the socket for clients
176 | self.serverTransport.listen()
177 | while True:
178 | try:
179 | client = self.serverTransport.accept()
180 | self.clients.put(client)
181 | except Exception, x:
182 | logging.exception(x)
183 |
184 |
185 | class TForkingServer(TServer):
186 |
187 | """A Thrift server that forks a new process for each request"""
188 | """
189 | This is more scalable than the threaded server as it does not cause
190 | GIL contention.
191 |
192 | Note that this has different semantics from the threading server.
193 | Specifically, updates to shared variables will no longer be shared.
194 | It will also not work on windows.
195 |
196 | This code is heavily inspired by SocketServer.ForkingMixIn in the
197 | Python stdlib.
198 | """
199 |
200 | def __init__(self, *args):
201 | TServer.__init__(self, *args)
202 | self.children = []
203 |
204 | def serve(self):
205 | def try_close(file):
206 | try:
207 | file.close()
208 | except IOError, e:
209 | logging.warning(e, exc_info=True)
210 |
211 |
212 | self.serverTransport.listen()
213 | while True:
214 | client = self.serverTransport.accept()
215 | try:
216 | pid = os.fork()
217 |
218 | if pid: # parent
219 | # add before collect, otherwise you race w/ waitpid
220 | self.children.append(pid)
221 | self.collect_children()
222 |
223 | # Parent must close socket or the connection may not get
224 | # closed promptly
225 | itrans = self.inputTransportFactory.getTransport(client)
226 | otrans = self.outputTransportFactory.getTransport(client)
227 | try_close(itrans)
228 | try_close(otrans)
229 | else:
230 | itrans = self.inputTransportFactory.getTransport(client)
231 | otrans = self.outputTransportFactory.getTransport(client)
232 |
233 | iprot = self.inputProtocolFactory.getProtocol(itrans)
234 | oprot = self.outputProtocolFactory.getProtocol(otrans)
235 |
236 | ecode = 0
237 | try:
238 | try:
239 | while True:
240 | self.processor.process(iprot, oprot)
241 | except TTransport.TTransportException, tx:
242 | pass
243 | except Exception, e:
244 | logging.exception(e)
245 | ecode = 1
246 | finally:
247 | try_close(itrans)
248 | try_close(otrans)
249 |
250 | os._exit(ecode)
251 |
252 | except TTransport.TTransportException, tx:
253 | pass
254 | except Exception, x:
255 | logging.exception(x)
256 |
257 |
258 | def collect_children(self):
259 | while self.children:
260 | try:
261 | pid, status = os.waitpid(0, os.WNOHANG)
262 | except os.error:
263 | pid = None
264 |
265 | if pid:
266 | self.children.remove(pid)
267 | else:
268 | break
269 |
270 |
271 |
--------------------------------------------------------------------------------
/src/thrift/transport/TTransport.py:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 | #
19 |
20 | from cStringIO import StringIO
21 | from struct import pack,unpack
22 | from thrift.Thrift import TException
23 |
24 | class TTransportException(TException):
25 |
26 | """Custom Transport Exception class"""
27 |
28 | UNKNOWN = 0
29 | NOT_OPEN = 1
30 | ALREADY_OPEN = 2
31 | TIMED_OUT = 3
32 | END_OF_FILE = 4
33 |
34 | def __init__(self, type=UNKNOWN, message=None):
35 | TException.__init__(self, message)
36 | self.type = type
37 |
38 | class TTransportBase:
39 |
40 | """Base class for Thrift transport layer."""
41 |
42 | def isOpen(self):
43 | pass
44 |
45 | def open(self):
46 | pass
47 |
48 | def close(self):
49 | pass
50 |
51 | def read(self, sz):
52 | pass
53 |
54 | def readAll(self, sz):
55 | buff = ''
56 | have = 0
57 | while (have < sz):
58 | chunk = self.read(sz-have)
59 | have += len(chunk)
60 | buff += chunk
61 |
62 | if len(chunk) == 0:
63 | raise EOFError()
64 |
65 | return buff
66 |
67 | def write(self, buf):
68 | pass
69 |
70 | def flush(self):
71 | pass
72 |
73 | # This class should be thought of as an interface.
74 | class CReadableTransport:
75 | """base class for transports that are readable from C"""
76 |
77 | # TODO(dreiss): Think about changing this interface to allow us to use
78 | # a (Python, not c) StringIO instead, because it allows
79 | # you to write after reading.
80 |
81 | # NOTE: This is a classic class, so properties will NOT work
82 | # correctly for setting.
83 | @property
84 | def cstringio_buf(self):
85 | """A cStringIO buffer that contains the current chunk we are reading."""
86 | pass
87 |
88 | def cstringio_refill(self, partialread, reqlen):
89 | """Refills cstringio_buf.
90 |
91 | Returns the currently used buffer (which can but need not be the same as
92 | the old cstringio_buf). partialread is what the C code has read from the
93 | buffer, and should be inserted into the buffer before any more reads. The
94 | return value must be a new, not borrowed reference. Something along the
95 | lines of self._buf should be fine.
96 |
97 | If reqlen bytes can't be read, throw EOFError.
98 | """
99 | pass
100 |
101 | class TServerTransportBase:
102 |
103 | """Base class for Thrift server transports."""
104 |
105 | def listen(self):
106 | pass
107 |
108 | def accept(self):
109 | pass
110 |
111 | def close(self):
112 | pass
113 |
114 | class TTransportFactoryBase:
115 |
116 | """Base class for a Transport Factory"""
117 |
118 | def getTransport(self, trans):
119 | return trans
120 |
121 | class TBufferedTransportFactory:
122 |
123 | """Factory transport that builds buffered transports"""
124 |
125 | def getTransport(self, trans):
126 | buffered = TBufferedTransport(trans)
127 | return buffered
128 |
129 |
130 | class TBufferedTransport(TTransportBase,CReadableTransport):
131 |
132 | """Class that wraps another transport and buffers its I/O."""
133 |
134 | DEFAULT_BUFFER = 4096
135 |
136 | def __init__(self, trans):
137 | self.__trans = trans
138 | self.__wbuf = StringIO()
139 | self.__rbuf = StringIO("")
140 |
141 | def isOpen(self):
142 | return self.__trans.isOpen()
143 |
144 | def open(self):
145 | return self.__trans.open()
146 |
147 | def close(self):
148 | return self.__trans.close()
149 |
150 | def read(self, sz):
151 | ret = self.__rbuf.read(sz)
152 | if len(ret) != 0:
153 | return ret
154 |
155 | self.__rbuf = StringIO(self.__trans.read(max(sz, self.DEFAULT_BUFFER)))
156 | return self.__rbuf.read(sz)
157 |
158 | def write(self, buf):
159 | self.__wbuf.write(buf)
160 |
161 | def flush(self):
162 | out = self.__wbuf.getvalue()
163 | # reset wbuf before write/flush to preserve state on underlying failure
164 | self.__wbuf = StringIO()
165 | self.__trans.write(out)
166 | self.__trans.flush()
167 |
168 | # Implement the CReadableTransport interface.
169 | @property
170 | def cstringio_buf(self):
171 | return self.__rbuf
172 |
173 | def cstringio_refill(self, partialread, reqlen):
174 | retstring = partialread
175 | if reqlen < self.DEFAULT_BUFFER:
176 | # try to make a read of as much as we can.
177 | retstring += self.__trans.read(self.DEFAULT_BUFFER)
178 |
179 | # but make sure we do read reqlen bytes.
180 | if len(retstring) < reqlen:
181 | retstring += self.__trans.readAll(reqlen - len(retstring))
182 |
183 | self.__rbuf = StringIO(retstring)
184 | return self.__rbuf
185 |
186 | class TMemoryBuffer(TTransportBase, CReadableTransport):
187 | """Wraps a cStringIO object as a TTransport.
188 |
189 | NOTE: Unlike the C++ version of this class, you cannot write to it
190 | then immediately read from it. If you want to read from a
191 | TMemoryBuffer, you must either pass a string to the constructor.
192 | TODO(dreiss): Make this work like the C++ version.
193 | """
194 |
195 | def __init__(self, value=None):
196 | """value -- a value to read from for stringio
197 |
198 | If value is set, this will be a transport for reading,
199 | otherwise, it is for writing"""
200 | if value is not None:
201 | self._buffer = StringIO(value)
202 | else:
203 | self._buffer = StringIO()
204 |
205 | def isOpen(self):
206 | return not self._buffer.closed
207 |
208 | def open(self):
209 | pass
210 |
211 | def close(self):
212 | self._buffer.close()
213 |
214 | def read(self, sz):
215 | return self._buffer.read(sz)
216 |
217 | def write(self, buf):
218 | self._buffer.write(buf)
219 |
220 | def flush(self):
221 | pass
222 |
223 | def getvalue(self):
224 | return self._buffer.getvalue()
225 |
226 | # Implement the CReadableTransport interface.
227 | @property
228 | def cstringio_buf(self):
229 | return self._buffer
230 |
231 | def cstringio_refill(self, partialread, reqlen):
232 | # only one shot at reading...
233 | raise EOFError()
234 |
235 | class TFramedTransportFactory:
236 |
237 | """Factory transport that builds framed transports"""
238 |
239 | def getTransport(self, trans):
240 | framed = TFramedTransport(trans)
241 | return framed
242 |
243 |
244 | class TFramedTransport(TTransportBase, CReadableTransport):
245 |
246 | """Class that wraps another transport and frames its I/O when writing."""
247 |
248 | def __init__(self, trans,):
249 | self.__trans = trans
250 | self.__rbuf = StringIO()
251 | self.__wbuf = StringIO()
252 |
253 | def isOpen(self):
254 | return self.__trans.isOpen()
255 |
256 | def open(self):
257 | return self.__trans.open()
258 |
259 | def close(self):
260 | return self.__trans.close()
261 |
262 | def read(self, sz):
263 | ret = self.__rbuf.read(sz)
264 | if len(ret) != 0:
265 | return ret
266 |
267 | self.readFrame()
268 | return self.__rbuf.read(sz)
269 |
270 | def readFrame(self):
271 | buff = self.__trans.readAll(4)
272 | sz, = unpack('!i', buff)
273 | self.__rbuf = StringIO(self.__trans.readAll(sz))
274 |
275 | def write(self, buf):
276 | self.__wbuf.write(buf)
277 |
278 | def flush(self):
279 | wout = self.__wbuf.getvalue()
280 | wsz = len(wout)
281 | # reset wbuf before write/flush to preserve state on underlying failure
282 | self.__wbuf = StringIO()
283 | # N.B.: Doing this string concatenation is WAY cheaper than making
284 | # two separate calls to the underlying socket object. Socket writes in
285 | # Python turn out to be REALLY expensive, but it seems to do a pretty
286 | # good job of managing string buffer operations without excessive copies
287 | buf = pack("!i", wsz) + wout
288 | self.__trans.write(buf)
289 | self.__trans.flush()
290 |
291 | # Implement the CReadableTransport interface.
292 | @property
293 | def cstringio_buf(self):
294 | return self.__rbuf
295 |
296 | def cstringio_refill(self, prefix, reqlen):
297 | # self.__rbuf will already be empty here because fastbinary doesn't
298 | # ask for a refill until the previous buffer is empty. Therefore,
299 | # we can start reading new frames immediately.
300 | while len(prefix) < reqlen:
301 | self.readFrame()
302 | prefix += self.__rbuf.getvalue()
303 | self.__rbuf = StringIO(prefix)
304 | return self.__rbuf
305 |
306 |
307 | class TFileObjectTransport(TTransportBase):
308 | """Wraps a file-like object to make it work as a Thrift transport."""
309 |
310 | def __init__(self, fileobj):
311 | self.fileobj = fileobj
312 |
313 | def isOpen(self):
314 | return True
315 |
316 | def close(self):
317 | self.fileobj.close()
318 |
319 | def read(self, sz):
320 | return self.fileobj.read(sz)
321 |
322 | def write(self, buf):
323 | self.fileobj.write(buf)
324 |
325 | def flush(self):
326 | self.fileobj.flush()
327 |
--------------------------------------------------------------------------------
/src/evernote/edam/error/ttypes.py:
--------------------------------------------------------------------------------
1 | #
2 | # Autogenerated by Thrift
3 | #
4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5 | #
6 |
7 | from thrift.Thrift import *
8 |
9 | from thrift.transport import TTransport
10 | from thrift.protocol import TBinaryProtocol
11 | try:
12 | from thrift.protocol import fastbinary
13 | except:
14 | fastbinary = None
15 |
16 |
17 | class EDAMErrorCode(object):
18 | """
19 | Numeric codes indicating the type of error that occurred on the
20 | service.
21 |