├── requests ├── packages │ ├── urllib3 │ │ ├── contrib │ │ │ ├── __init__.py │ │ │ └── ntlmpool.py │ │ ├── packages │ │ │ ├── __init__.py │ │ │ └── ssl_match_hostname │ │ │ │ ├── __init__.py │ │ │ │ └── _implementation.py │ │ ├── util │ │ │ ├── __init__.py │ │ │ ├── request.py │ │ │ ├── response.py │ │ │ ├── connection.py │ │ │ └── url.py │ │ ├── filepost.py │ │ ├── __init__.py │ │ ├── exceptions.py │ │ ├── request.py │ │ └── fields.py │ ├── chardet │ │ ├── compat.py │ │ ├── __init__.py │ │ ├── constants.py │ │ ├── euctwprober.py │ │ ├── euckrprober.py │ │ ├── gb2312prober.py │ │ ├── big5prober.py │ │ ├── cp949prober.py │ │ ├── charsetprober.py │ │ ├── mbcsgroupprober.py │ │ ├── codingstatemachine.py │ │ ├── chardetect.py │ │ ├── utf8prober.py │ │ ├── escprober.py │ │ ├── sbcsgroupprober.py │ │ ├── mbcharsetprober.py │ │ ├── eucjpprober.py │ │ ├── sjisprober.py │ │ ├── charsetgroupprober.py │ │ ├── sbcharsetprober.py │ │ ├── latin1prober.py │ │ └── universaldetector.py │ └── __init__.py ├── certs.py ├── hooks.py ├── compat.py ├── __init__.py ├── exceptions.py ├── structures.py ├── status_codes.py └── api.py ├── icon.png ├── images └── 74681984gw1f5xbkf7f9oj20nh0geabb.jpeg ├── weibo ├── __init__.py ├── LICENSE.txt └── weibo.py ├── get_image_url.py ├── get_markdown.py ├── LICENSE ├── README.md ├── upload.py ├── .gitignore ├── rsa ├── __init__.py ├── core.py ├── asn1.py ├── parallel.py ├── randnum.py ├── util.py ├── pem.py ├── _compat.py ├── prime.py ├── common.py ├── bigfile.py └── varblock.py ├── util.py ├── clipboard.py ├── info_for_v2.plist └── info.plist /requests/packages/urllib3/contrib/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EkkoG/WeiboPictureWorkflow/HEAD/icon.png -------------------------------------------------------------------------------- /images/74681984gw1f5xbkf7f9oj20nh0geabb.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EkkoG/WeiboPictureWorkflow/HEAD/images/74681984gw1f5xbkf7f9oj20nh0geabb.jpeg -------------------------------------------------------------------------------- /requests/packages/urllib3/packages/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from . import ssl_match_hostname 4 | 5 | __all__ = ('ssl_match_hostname', ) 6 | -------------------------------------------------------------------------------- /weibo/__init__.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # vim:fenc=utf-8 4 | # 5 | # Copyright © 2016 ciel 6 | # 7 | # Distributed under terms of the MIT license. 8 | 9 | """ 10 | init 11 | """ 12 | 13 | 14 | -------------------------------------------------------------------------------- /get_image_url.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # vim:fenc=utf-8 4 | # 5 | # Copyright © 2016 ciel 6 | # 7 | # Distributed under terms of the MIT license. 8 | 9 | """ 10 | 得到图片的 URL 11 | """ 12 | 13 | from upload import upload_file 14 | import util 15 | import os 16 | import sys 17 | 18 | 19 | url = upload_file() 20 | if url: 21 | os.system("echo '%s' | pbcopy" % url) 22 | util.alert('上传图片成功,图片 URL 已复制到剪切板!') 23 | else: 24 | util.alrt('上传失败!') 25 | sys.exit(0) 26 | -------------------------------------------------------------------------------- /requests/packages/urllib3/packages/ssl_match_hostname/__init__.py: -------------------------------------------------------------------------------- 1 | try: 2 | # Python 3.2+ 3 | from ssl import CertificateError, match_hostname 4 | except ImportError: 5 | try: 6 | # Backport of the function from a pypi module 7 | from backports.ssl_match_hostname import CertificateError, match_hostname 8 | except ImportError: 9 | # Our vendored copy 10 | from ._implementation import CertificateError, match_hostname 11 | 12 | # Not needed, but documenting what we provide. 13 | __all__ = ('CertificateError', 'match_hostname') 14 | -------------------------------------------------------------------------------- /get_markdown.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # vim:fenc=utf-8 4 | # 5 | # Copyright © 2016 ciel 6 | # 7 | # Distributed under terms of the MIT license. 8 | 9 | """ 10 | 得到图片的 Markdown 11 | """ 12 | 13 | from upload import upload_file 14 | import util 15 | import os 16 | import sys 17 | 18 | 19 | url = upload_file() 20 | if url: 21 | markdown_url = '![](%s)' % (url) 22 | os.system("echo '%s' | pbcopy" % markdown_url) 23 | util.alert('上传图片成功,图片 Markdown 已复制到剪切板!') 24 | else: 25 | util.alert('上传失败!') 26 | sys.exit(0) 27 | -------------------------------------------------------------------------------- /requests/certs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | certs.py 6 | ~~~~~~~~ 7 | 8 | This module returns the preferred default CA certificate bundle. 9 | 10 | If you are packaging Requests, e.g., for a Linux distribution or a managed 11 | environment, you can change the definition of where() to return a separately 12 | packaged CA bundle. 13 | """ 14 | import os.path 15 | 16 | try: 17 | from certifi import where 18 | except ImportError: 19 | def where(): 20 | """Return the preferred certificate bundle.""" 21 | # vendored bundle inside Requests 22 | return os.path.join(os.path.dirname(__file__), 'cacert.pem') 23 | 24 | if __name__ == '__main__': 25 | print(where()) 26 | -------------------------------------------------------------------------------- /requests/hooks.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | requests.hooks 5 | ~~~~~~~~~~~~~~ 6 | 7 | This module provides the capabilities for the Requests hooks system. 8 | 9 | Available hooks: 10 | 11 | ``response``: 12 | The response generated from a Request. 13 | 14 | """ 15 | HOOKS = ['response'] 16 | 17 | def default_hooks(): 18 | return dict((event, []) for event in HOOKS) 19 | 20 | # TODO: response is the only one 21 | 22 | 23 | def dispatch_hook(key, hooks, hook_data, **kwargs): 24 | """Dispatches a hook dictionary on a given piece of data.""" 25 | hooks = hooks or dict() 26 | hooks = hooks.get(key) 27 | if hooks: 28 | if hasattr(hooks, '__call__'): 29 | hooks = [hooks] 30 | for hook in hooks: 31 | _hook_data = hook(hook_data, **kwargs) 32 | if _hook_data is not None: 33 | hook_data = _hook_data 34 | return hook_data 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Cielpy 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /requests/packages/urllib3/util/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | # For backwards compatibility, provide imports that used to be here. 3 | from .connection import is_connection_dropped 4 | from .request import make_headers 5 | from .response import is_fp_closed 6 | from .ssl_ import ( 7 | SSLContext, 8 | HAS_SNI, 9 | assert_fingerprint, 10 | resolve_cert_reqs, 11 | resolve_ssl_version, 12 | ssl_wrap_socket, 13 | ) 14 | from .timeout import ( 15 | current_time, 16 | Timeout, 17 | ) 18 | 19 | from .retry import Retry 20 | from .url import ( 21 | get_host, 22 | parse_url, 23 | split_first, 24 | Url, 25 | ) 26 | 27 | __all__ = ( 28 | 'HAS_SNI', 29 | 'SSLContext', 30 | 'Retry', 31 | 'Timeout', 32 | 'Url', 33 | 'assert_fingerprint', 34 | 'current_time', 35 | 'is_connection_dropped', 36 | 'is_fp_closed', 37 | 'get_host', 38 | 'parse_url', 39 | 'make_headers', 40 | 'resolve_cert_reqs', 41 | 'resolve_ssl_version', 42 | 'split_first', 43 | 'ssl_wrap_socket', 44 | ) 45 | -------------------------------------------------------------------------------- /weibo/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 brian 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /requests/packages/chardet/compat.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # Contributor(s): 3 | # Ian Cordasco - port to Python 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18 | # 02110-1301 USA 19 | ######################### END LICENSE BLOCK ######################### 20 | 21 | import sys 22 | 23 | 24 | if sys.version_info < (3, 0): 25 | base_str = (str, unicode) 26 | else: 27 | base_str = (bytes, str) 28 | 29 | 30 | def wrap_ord(a): 31 | if sys.version_info < (3, 0) and isinstance(a, base_str): 32 | return ord(a) 33 | else: 34 | return a 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 一个 Alfred Workflow,可以上传剪切板图片到新浪微博,并复制 URL 到剪切板 2 | 详情和制作过程见: 3 | 4 | [https://imciel.com/2016/07/17/weibo-picture-upload-alfred-workflow/](https://imciel.com/2016/07/17/weibo-picture-upload-alfred-workflow/) 5 | 6 | ### 使用方法 7 | 8 | 在 [Release](https://github.com/cielpy/WeiboPictureWorkflow/releases) 页下载最新的 Workflow 安装即可,安装完成后设置自己的快捷键 9 | 10 | ![](https://github.com/cielpy/WeiboPictureWorkflow/blob/master/images/74681984gw1f5xbkf7f9oj20nh0geabb.jpeg) 11 | 12 | 上方是单独生成 URL 的,下方是生成 Markdown 格式字符串的,可以根据自己的喜好设置。 13 | 14 | 设置快捷键完成后,按快捷键激活 Workflow,会提示没有,并打开一个配置文件,需要在这个文件中输入微博用户名和密码,用于模拟登录,登录完成后会删除这个配置文件。 15 | 16 | 登录完成后就可以上传图片了,截图或者复制一张图片,按刚才设置的快捷键,上传完成后会有提示。提示 URL 已复制到剪切板的话,说明已经上传成功,这个时候就可以粘贴到你想要粘贴的地方了。 17 | 18 | #### 对于 Alfred 2 用户 19 | 20 | 由于本人日常使用 Alfred 3,开发也使用的 Alfred 3,导出的 workflow 不能在 Alfred 2 上使用,深感抱歉,这里提供一个办法可以使 Alfred 2 用户也能使用这个 Workflow 21 | 22 | 1. 安装 [Release](https://github.com/cielpy/WeiboPictureWorkflow/releases) 中最新版本的 Workflow 23 | 2. 下载 Alfred 2 专用的 info.plist 文件,链接 https://github.com/cielpy/WeiboPictureWorkflow/blob/master/info_for_v2.plist?raw=true 24 | 3. 在 Workflow 列表中找到本 Workflow,右键 Show in Finder,使用第 2 步下载下来的 plist 文件替换掉目录下的 info.plist 文件即可。 25 | 26 | ### 鸣谢 27 | 28 | 此项目中很多源码取自 https://github.com/tiann/markdown-img-upload 和 https://github.com/trytofix/hexo_weibo_image ,在这里非常感谢两位作者的付出。 29 | 30 | 31 | -------------------------------------------------------------------------------- /requests/packages/chardet/__init__.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # This library is free software; you can redistribute it and/or 3 | # modify it under the terms of the GNU Lesser General Public 4 | # License as published by the Free Software Foundation; either 5 | # version 2.1 of the License, or (at your option) any later version. 6 | # 7 | # This library is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | # Lesser General Public License for more details. 11 | # 12 | # You should have received a copy of the GNU Lesser General Public 13 | # License along with this library; if not, write to the Free Software 14 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 15 | # 02110-1301 USA 16 | ######################### END LICENSE BLOCK ######################### 17 | 18 | __version__ = "2.3.0" 19 | from sys import version_info 20 | 21 | 22 | def detect(aBuf): 23 | if ((version_info < (3, 0) and isinstance(aBuf, unicode)) or 24 | (version_info >= (3, 0) and not isinstance(aBuf, bytes))): 25 | raise ValueError('Expected a bytes object, not a unicode object') 26 | 27 | from . import universaldetector 28 | u = universaldetector.UniversalDetector() 29 | u.reset() 30 | u.feed(aBuf) 31 | u.close() 32 | return u.result 33 | -------------------------------------------------------------------------------- /requests/packages/chardet/constants.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Universal charset detector code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 2001 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # Shy Shalom - original C code 12 | # 13 | # This library is free software; you can redistribute it and/or 14 | # modify it under the terms of the GNU Lesser General Public 15 | # License as published by the Free Software Foundation; either 16 | # version 2.1 of the License, or (at your option) any later version. 17 | # 18 | # This library is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | # Lesser General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Lesser General Public 24 | # License along with this library; if not, write to the Free Software 25 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 26 | # 02110-1301 USA 27 | ######################### END LICENSE BLOCK ######################### 28 | 29 | _debug = 0 30 | 31 | eDetecting = 0 32 | eFoundIt = 1 33 | eNotMe = 2 34 | 35 | eStart = 0 36 | eError = 1 37 | eItsMe = 2 38 | 39 | SHORTCUT_THRESHOLD = 0.95 40 | -------------------------------------------------------------------------------- /upload.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # vim:fenc=utf-8 4 | # 5 | # Copyright © 2016 ciel 6 | # 7 | # Distributed under terms of the MIT license. 8 | 9 | import util 10 | import sys 11 | from weibo import weibo 12 | from clipboard import get_paste_img_file 13 | 14 | 15 | def upload_file(): 16 | if not weibo.check_login_status(): 17 | if not util.check_config_file(): 18 | util.generate_config() 19 | 20 | config = util.read_config() 21 | 22 | if not config: 23 | util.alert('请先设置你的微博账号') 24 | util.open_with_editor() 25 | sys.exit(0) 26 | 27 | username = config['username'] 28 | password = config['password'] 29 | 30 | try: 31 | weibo.login_with_username_and_password(username, password) 32 | except: 33 | util.alert('登录失败,请重试!') 34 | sys.exit(0) 35 | 36 | 37 | if weibo.check_login_status(): 38 | util.delete_config() 39 | else: 40 | util.alert('登录失败,请重试!') 41 | sys.exit(0) 42 | 43 | img_file = get_paste_img_file() 44 | 45 | if img_file: 46 | try: 47 | url = weibo.request_image_url(img_file.name) 48 | return url 49 | except: 50 | util.delete_cookie() 51 | util.alert('Cookie 过期,请重新登录!') 52 | sys.exit(0) 53 | return None 54 | else: 55 | util.alert('您的剪切板里没有图片!') 56 | sys.exit(0) 57 | -------------------------------------------------------------------------------- /requests/packages/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Debian and other distributions "unbundle" requests' vendored dependencies, and 3 | rewrite all imports to use the global versions of ``urllib3`` and ``chardet``. 4 | The problem with this is that not only requests itself imports those 5 | dependencies, but third-party code outside of the distros' control too. 6 | 7 | In reaction to these problems, the distro maintainers replaced 8 | ``requests.packages`` with a magical "stub module" that imports the correct 9 | modules. The implementations were varying in quality and all had severe 10 | problems. For example, a symlink (or hardlink) that links the correct modules 11 | into place introduces problems regarding object identity, since you now have 12 | two modules in `sys.modules` with the same API, but different identities:: 13 | 14 | requests.packages.urllib3 is not urllib3 15 | 16 | With version ``2.5.2``, requests started to maintain its own stub, so that 17 | distro-specific breakage would be reduced to a minimum, even though the whole 18 | issue is not requests' fault in the first place. See 19 | https://github.com/kennethreitz/requests/pull/2375 for the corresponding pull 20 | request. 21 | ''' 22 | 23 | from __future__ import absolute_import 24 | import sys 25 | 26 | try: 27 | from . import urllib3 28 | except ImportError: 29 | import urllib3 30 | sys.modules['%s.urllib3' % __name__] = urllib3 31 | 32 | try: 33 | from . import chardet 34 | except ImportError: 35 | import chardet 36 | sys.modules['%s.chardet' % __name__] = chardet 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/python 2 | 3 | ### Python ### 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | env/ 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *,cover 49 | .hypothesis/ 50 | 51 | # Translations 52 | *.mo 53 | *.pot 54 | 55 | # Django stuff: 56 | *.log 57 | local_settings.py 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # IPython Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # dotenv 82 | .env 83 | 84 | # virtualenv 85 | venv/ 86 | ENV/ 87 | 88 | # Spyder project settings 89 | .spyderproject 90 | 91 | # Rope project settings 92 | .ropeproject 93 | 94 | config.ini 95 | cookie.txt 96 | -------------------------------------------------------------------------------- /rsa/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Sybren A. Stüvel 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | """RSA module 17 | 18 | Module for calculating large primes, and RSA encryption, decryption, signing 19 | and verification. Includes generating public and private keys. 20 | 21 | WARNING: this implementation does not use random padding, compression of the 22 | cleartext input to prevent repetitions, or other common security improvements. 23 | Use with care. 24 | 25 | """ 26 | 27 | from rsa.key import newkeys, PrivateKey, PublicKey 28 | from rsa.pkcs1 import encrypt, decrypt, sign, verify, DecryptionError, \ 29 | VerificationError 30 | 31 | __author__ = "Sybren Stuvel, Barry Mead and Yesudeep Mangalapilly" 32 | __date__ = "2016-03-29" 33 | __version__ = '3.4.2' 34 | 35 | # Do doctest if we're run directly 36 | if __name__ == "__main__": 37 | import doctest 38 | 39 | doctest.testmod() 40 | 41 | __all__ = ["newkeys", "encrypt", "decrypt", "sign", "verify", 'PublicKey', 42 | 'PrivateKey', 'DecryptionError', 'VerificationError'] 43 | -------------------------------------------------------------------------------- /requests/compat.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | pythoncompat 5 | """ 6 | 7 | from .packages import chardet 8 | 9 | import sys 10 | 11 | # ------- 12 | # Pythons 13 | # ------- 14 | 15 | # Syntax sugar. 16 | _ver = sys.version_info 17 | 18 | #: Python 2.x? 19 | is_py2 = (_ver[0] == 2) 20 | 21 | #: Python 3.x? 22 | is_py3 = (_ver[0] == 3) 23 | 24 | try: 25 | import simplejson as json 26 | except (ImportError, SyntaxError): 27 | # simplejson does not support Python 3.2, it throws a SyntaxError 28 | # because of u'...' Unicode literals. 29 | import json 30 | 31 | # --------- 32 | # Specifics 33 | # --------- 34 | 35 | if is_py2: 36 | from urllib import quote, unquote, quote_plus, unquote_plus, urlencode, getproxies, proxy_bypass 37 | from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag 38 | from urllib2 import parse_http_list 39 | import cookielib 40 | from Cookie import Morsel 41 | from StringIO import StringIO 42 | from .packages.urllib3.packages.ordered_dict import OrderedDict 43 | 44 | builtin_str = str 45 | bytes = str 46 | str = unicode 47 | basestring = basestring 48 | numeric_types = (int, long, float) 49 | 50 | elif is_py3: 51 | from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag 52 | from urllib.request import parse_http_list, getproxies, proxy_bypass 53 | from http import cookiejar as cookielib 54 | from http.cookies import Morsel 55 | from io import StringIO 56 | from collections import OrderedDict 57 | 58 | builtin_str = str 59 | str = str 60 | bytes = bytes 61 | basestring = (str, bytes) 62 | numeric_types = (int, float) 63 | -------------------------------------------------------------------------------- /util.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # vim:fenc=utf-8 4 | # 5 | # Copyright © 2016 ciel 6 | # 7 | # Distributed under terms of the MIT license. 8 | 9 | """ 10 | Workflow 配置工具 11 | """ 12 | 13 | import os, re, subprocess 14 | import ConfigParser 15 | from tempfile import NamedTemporaryFile 16 | 17 | CONFIG_FILE = 'config.ini' 18 | COOKIE_FILE = 'cookie.txt' 19 | 20 | def check_config_file(): 21 | return os.path.exists(CONFIG_FILE) 22 | 23 | def alert(msg, title="Warming!"): 24 | '''alrt user in notification center''' 25 | os.system('osascript -e \'display notification "%s" with title "%s"\'' % (msg, title)) 26 | 27 | def read_config(): 28 | ''' read config from config.ini, return a tuple''' 29 | if not os.path.exists(CONFIG_FILE): 30 | return 31 | cf = ConfigParser.ConfigParser() 32 | cf.read(CONFIG_FILE) 33 | 34 | weibo_section = 'weibo' 35 | keys = ('username', 'password') 36 | try: 37 | res = map(lambda x: cf.get(weibo_section, x), keys) 38 | except ConfigParser.NoOptionError: 39 | return 40 | 41 | if not all(map(lambda x: re.match(r'\w+', x), res)): 42 | return 43 | return dict(zip(keys, res)) 44 | 45 | def open_with_editor(): 46 | os.system('open -b "com.apple.TextEdit" "./%s"' % CONFIG_FILE) 47 | 48 | def delete_config(): 49 | os.system('/bin/rm "./%s"' % CONFIG_FILE) 50 | 51 | def delete_cookie(): 52 | os.system('/bin/rm "./%s"' % COOKIE_FILE) 53 | 54 | def generate_config(): 55 | import textwrap 56 | config_init_content = '''\ 57 | ; 用做模拟登录,得到 cookie 后则删除配置文件 58 | [weibo] 59 | username=微博登录用户名 60 | password=微博密码 61 | ''' 62 | with open(CONFIG_FILE, 'w') as fp: 63 | fp.write(textwrap.dedent(config_init_content)) 64 | -------------------------------------------------------------------------------- /requests/packages/chardet/euctwprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from .mbcharsetprober import MultiByteCharSetProber 29 | from .codingstatemachine import CodingStateMachine 30 | from .chardistribution import EUCTWDistributionAnalysis 31 | from .mbcssm import EUCTWSMModel 32 | 33 | class EUCTWProber(MultiByteCharSetProber): 34 | def __init__(self): 35 | MultiByteCharSetProber.__init__(self) 36 | self._mCodingSM = CodingStateMachine(EUCTWSMModel) 37 | self._mDistributionAnalyzer = EUCTWDistributionAnalysis() 38 | self.reset() 39 | 40 | def get_charset_name(self): 41 | return "EUC-TW" 42 | -------------------------------------------------------------------------------- /requests/packages/chardet/euckrprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from .mbcharsetprober import MultiByteCharSetProber 29 | from .codingstatemachine import CodingStateMachine 30 | from .chardistribution import EUCKRDistributionAnalysis 31 | from .mbcssm import EUCKRSMModel 32 | 33 | 34 | class EUCKRProber(MultiByteCharSetProber): 35 | def __init__(self): 36 | MultiByteCharSetProber.__init__(self) 37 | self._mCodingSM = CodingStateMachine(EUCKRSMModel) 38 | self._mDistributionAnalyzer = EUCKRDistributionAnalysis() 39 | self.reset() 40 | 41 | def get_charset_name(self): 42 | return "EUC-KR" 43 | -------------------------------------------------------------------------------- /requests/packages/chardet/gb2312prober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from .mbcharsetprober import MultiByteCharSetProber 29 | from .codingstatemachine import CodingStateMachine 30 | from .chardistribution import GB2312DistributionAnalysis 31 | from .mbcssm import GB2312SMModel 32 | 33 | class GB2312Prober(MultiByteCharSetProber): 34 | def __init__(self): 35 | MultiByteCharSetProber.__init__(self) 36 | self._mCodingSM = CodingStateMachine(GB2312SMModel) 37 | self._mDistributionAnalyzer = GB2312DistributionAnalysis() 38 | self.reset() 39 | 40 | def get_charset_name(self): 41 | return "GB2312" 42 | -------------------------------------------------------------------------------- /requests/packages/chardet/big5prober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Communicator client code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from .mbcharsetprober import MultiByteCharSetProber 29 | from .codingstatemachine import CodingStateMachine 30 | from .chardistribution import Big5DistributionAnalysis 31 | from .mbcssm import Big5SMModel 32 | 33 | 34 | class Big5Prober(MultiByteCharSetProber): 35 | def __init__(self): 36 | MultiByteCharSetProber.__init__(self) 37 | self._mCodingSM = CodingStateMachine(Big5SMModel) 38 | self._mDistributionAnalyzer = Big5DistributionAnalysis() 39 | self.reset() 40 | 41 | def get_charset_name(self): 42 | return "Big5" 43 | -------------------------------------------------------------------------------- /rsa/core.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Sybren A. Stüvel 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Core mathematical operations. 18 | 19 | This is the actual core RSA implementation, which is only defined 20 | mathematically on integers. 21 | """ 22 | 23 | from rsa._compat import is_integer 24 | 25 | 26 | def assert_int(var, name): 27 | if is_integer(var): 28 | return 29 | 30 | raise TypeError('%s should be an integer, not %s' % (name, var.__class__)) 31 | 32 | 33 | def encrypt_int(message, ekey, n): 34 | """Encrypts a message using encryption key 'ekey', working modulo n""" 35 | 36 | assert_int(message, 'message') 37 | assert_int(ekey, 'ekey') 38 | assert_int(n, 'n') 39 | 40 | if message < 0: 41 | raise ValueError('Only non-negative numbers are supported') 42 | 43 | if message > n: 44 | raise OverflowError("The message %i is too long for n=%i" % (message, n)) 45 | 46 | return pow(message, ekey, n) 47 | 48 | 49 | def decrypt_int(cyphertext, dkey, n): 50 | """Decrypts a cypher text using the decryption key 'dkey', working modulo n""" 51 | 52 | assert_int(cyphertext, 'cyphertext') 53 | assert_int(dkey, 'dkey') 54 | assert_int(n, 'n') 55 | 56 | message = pow(cyphertext, dkey, n) 57 | return message 58 | -------------------------------------------------------------------------------- /requests/packages/chardet/cp949prober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from .mbcharsetprober import MultiByteCharSetProber 29 | from .codingstatemachine import CodingStateMachine 30 | from .chardistribution import EUCKRDistributionAnalysis 31 | from .mbcssm import CP949SMModel 32 | 33 | 34 | class CP949Prober(MultiByteCharSetProber): 35 | def __init__(self): 36 | MultiByteCharSetProber.__init__(self) 37 | self._mCodingSM = CodingStateMachine(CP949SMModel) 38 | # NOTE: CP949 is a superset of EUC-KR, so the distribution should be 39 | # not different. 40 | self._mDistributionAnalyzer = EUCKRDistributionAnalysis() 41 | self.reset() 42 | 43 | def get_charset_name(self): 44 | return "CP949" 45 | -------------------------------------------------------------------------------- /rsa/asn1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Sybren A. Stüvel 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """ASN.1 definitions. 18 | 19 | Not all ASN.1-handling code use these definitions, but when it does, they should be here. 20 | """ 21 | 22 | from pyasn1.type import univ, namedtype, tag 23 | 24 | 25 | class PubKeyHeader(univ.Sequence): 26 | componentType = namedtype.NamedTypes( 27 | namedtype.NamedType('oid', univ.ObjectIdentifier()), 28 | namedtype.NamedType('parameters', univ.Null()), 29 | ) 30 | 31 | 32 | class OpenSSLPubKey(univ.Sequence): 33 | componentType = namedtype.NamedTypes( 34 | namedtype.NamedType('header', PubKeyHeader()), 35 | 36 | # This little hack (the implicit tag) allows us to get a Bit String as Octet String 37 | namedtype.NamedType('key', univ.OctetString().subtype( 38 | implicitTag=tag.Tag(tagClass=0, tagFormat=0, tagId=3))), 39 | ) 40 | 41 | 42 | class AsnPubKey(univ.Sequence): 43 | """ASN.1 contents of DER encoded public key: 44 | 45 | RSAPublicKey ::= SEQUENCE { 46 | modulus INTEGER, -- n 47 | publicExponent INTEGER, -- e 48 | """ 49 | 50 | componentType = namedtype.NamedTypes( 51 | namedtype.NamedType('modulus', univ.Integer()), 52 | namedtype.NamedType('publicExponent', univ.Integer()), 53 | ) 54 | -------------------------------------------------------------------------------- /requests/packages/chardet/charsetprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Universal charset detector code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 2001 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # Shy Shalom - original C code 12 | # 13 | # This library is free software; you can redistribute it and/or 14 | # modify it under the terms of the GNU Lesser General Public 15 | # License as published by the Free Software Foundation; either 16 | # version 2.1 of the License, or (at your option) any later version. 17 | # 18 | # This library is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | # Lesser General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Lesser General Public 24 | # License along with this library; if not, write to the Free Software 25 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 26 | # 02110-1301 USA 27 | ######################### END LICENSE BLOCK ######################### 28 | 29 | from . import constants 30 | import re 31 | 32 | 33 | class CharSetProber: 34 | def __init__(self): 35 | pass 36 | 37 | def reset(self): 38 | self._mState = constants.eDetecting 39 | 40 | def get_charset_name(self): 41 | return None 42 | 43 | def feed(self, aBuf): 44 | pass 45 | 46 | def get_state(self): 47 | return self._mState 48 | 49 | def get_confidence(self): 50 | return 0.0 51 | 52 | def filter_high_bit_only(self, aBuf): 53 | aBuf = re.sub(b'([\x00-\x7F])+', b' ', aBuf) 54 | return aBuf 55 | 56 | def filter_without_english_letters(self, aBuf): 57 | aBuf = re.sub(b'([A-Za-z])+', b' ', aBuf) 58 | return aBuf 59 | 60 | def filter_with_english_letters(self, aBuf): 61 | # TODO 62 | return aBuf 63 | -------------------------------------------------------------------------------- /requests/packages/chardet/mbcsgroupprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Universal charset detector code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 2001 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # Shy Shalom - original C code 12 | # Proofpoint, Inc. 13 | # 14 | # This library is free software; you can redistribute it and/or 15 | # modify it under the terms of the GNU Lesser General Public 16 | # License as published by the Free Software Foundation; either 17 | # version 2.1 of the License, or (at your option) any later version. 18 | # 19 | # This library is distributed in the hope that it will be useful, 20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 | # Lesser General Public License for more details. 23 | # 24 | # You should have received a copy of the GNU Lesser General Public 25 | # License along with this library; if not, write to the Free Software 26 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 27 | # 02110-1301 USA 28 | ######################### END LICENSE BLOCK ######################### 29 | 30 | from .charsetgroupprober import CharSetGroupProber 31 | from .utf8prober import UTF8Prober 32 | from .sjisprober import SJISProber 33 | from .eucjpprober import EUCJPProber 34 | from .gb2312prober import GB2312Prober 35 | from .euckrprober import EUCKRProber 36 | from .cp949prober import CP949Prober 37 | from .big5prober import Big5Prober 38 | from .euctwprober import EUCTWProber 39 | 40 | 41 | class MBCSGroupProber(CharSetGroupProber): 42 | def __init__(self): 43 | CharSetGroupProber.__init__(self) 44 | self._mProbers = [ 45 | UTF8Prober(), 46 | SJISProber(), 47 | EUCJPProber(), 48 | GB2312Prober(), 49 | EUCKRProber(), 50 | CP949Prober(), 51 | Big5Prober(), 52 | EUCTWProber() 53 | ] 54 | self.reset() 55 | -------------------------------------------------------------------------------- /requests/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # __ 4 | # /__) _ _ _ _ _/ _ 5 | # / ( (- (/ (/ (- _) / _) 6 | # / 7 | 8 | """ 9 | Requests HTTP library 10 | ~~~~~~~~~~~~~~~~~~~~~ 11 | 12 | Requests is an HTTP library, written in Python, for human beings. Basic GET 13 | usage: 14 | 15 | >>> import requests 16 | >>> r = requests.get('https://www.python.org') 17 | >>> r.status_code 18 | 200 19 | >>> 'Python is a programming language' in r.content 20 | True 21 | 22 | ... or POST: 23 | 24 | >>> payload = dict(key1='value1', key2='value2') 25 | >>> r = requests.post('http://httpbin.org/post', data=payload) 26 | >>> print(r.text) 27 | { 28 | ... 29 | "form": { 30 | "key2": "value2", 31 | "key1": "value1" 32 | }, 33 | ... 34 | } 35 | 36 | The other HTTP methods are supported - see `requests.api`. Full documentation 37 | is at . 38 | 39 | :copyright: (c) 2015 by Kenneth Reitz. 40 | :license: Apache 2.0, see LICENSE for more details. 41 | 42 | """ 43 | 44 | __title__ = 'requests' 45 | __version__ = '2.9.1' 46 | __build__ = 0x020901 47 | __author__ = 'Kenneth Reitz' 48 | __license__ = 'Apache 2.0' 49 | __copyright__ = 'Copyright 2015 Kenneth Reitz' 50 | 51 | # Attempt to enable urllib3's SNI support, if possible 52 | try: 53 | from .packages.urllib3.contrib import pyopenssl 54 | pyopenssl.inject_into_urllib3() 55 | except ImportError: 56 | pass 57 | 58 | from . import utils 59 | from .models import Request, Response, PreparedRequest 60 | from .api import request, get, head, post, patch, put, delete, options 61 | from .sessions import session, Session 62 | from .status_codes import codes 63 | from .exceptions import ( 64 | RequestException, Timeout, URLRequired, 65 | TooManyRedirects, HTTPError, ConnectionError, 66 | FileModeWarning, 67 | ) 68 | 69 | # Set default logging handler to avoid "No handler found" warnings. 70 | import logging 71 | try: # Python 2.7+ 72 | from logging import NullHandler 73 | except ImportError: 74 | class NullHandler(logging.Handler): 75 | def emit(self, record): 76 | pass 77 | 78 | logging.getLogger(__name__).addHandler(NullHandler()) 79 | 80 | import warnings 81 | 82 | # FileModeWarnings go off per the default. 83 | warnings.simplefilter('default', FileModeWarning, append=True) 84 | -------------------------------------------------------------------------------- /requests/packages/urllib3/util/request.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from base64 import b64encode 3 | 4 | from ..packages.six import b 5 | 6 | ACCEPT_ENCODING = 'gzip,deflate' 7 | 8 | 9 | def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, 10 | basic_auth=None, proxy_basic_auth=None, disable_cache=None): 11 | """ 12 | Shortcuts for generating request headers. 13 | 14 | :param keep_alive: 15 | If ``True``, adds 'connection: keep-alive' header. 16 | 17 | :param accept_encoding: 18 | Can be a boolean, list, or string. 19 | ``True`` translates to 'gzip,deflate'. 20 | List will get joined by comma. 21 | String will be used as provided. 22 | 23 | :param user_agent: 24 | String representing the user-agent you want, such as 25 | "python-urllib3/0.6" 26 | 27 | :param basic_auth: 28 | Colon-separated username:password string for 'authorization: basic ...' 29 | auth header. 30 | 31 | :param proxy_basic_auth: 32 | Colon-separated username:password string for 'proxy-authorization: basic ...' 33 | auth header. 34 | 35 | :param disable_cache: 36 | If ``True``, adds 'cache-control: no-cache' header. 37 | 38 | Example:: 39 | 40 | >>> make_headers(keep_alive=True, user_agent="Batman/1.0") 41 | {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'} 42 | >>> make_headers(accept_encoding=True) 43 | {'accept-encoding': 'gzip,deflate'} 44 | """ 45 | headers = {} 46 | if accept_encoding: 47 | if isinstance(accept_encoding, str): 48 | pass 49 | elif isinstance(accept_encoding, list): 50 | accept_encoding = ','.join(accept_encoding) 51 | else: 52 | accept_encoding = ACCEPT_ENCODING 53 | headers['accept-encoding'] = accept_encoding 54 | 55 | if user_agent: 56 | headers['user-agent'] = user_agent 57 | 58 | if keep_alive: 59 | headers['connection'] = 'keep-alive' 60 | 61 | if basic_auth: 62 | headers['authorization'] = 'Basic ' + \ 63 | b64encode(b(basic_auth)).decode('utf-8') 64 | 65 | if proxy_basic_auth: 66 | headers['proxy-authorization'] = 'Basic ' + \ 67 | b64encode(b(proxy_basic_auth)).decode('utf-8') 68 | 69 | if disable_cache: 70 | headers['cache-control'] = 'no-cache' 71 | 72 | return headers 73 | -------------------------------------------------------------------------------- /requests/packages/urllib3/util/response.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from ..packages.six.moves import http_client as httplib 3 | 4 | from ..exceptions import HeaderParsingError 5 | 6 | 7 | def is_fp_closed(obj): 8 | """ 9 | Checks whether a given file-like object is closed. 10 | 11 | :param obj: 12 | The file-like object to check. 13 | """ 14 | 15 | try: 16 | # Check via the official file-like-object way. 17 | return obj.closed 18 | except AttributeError: 19 | pass 20 | 21 | try: 22 | # Check if the object is a container for another file-like object that 23 | # gets released on exhaustion (e.g. HTTPResponse). 24 | return obj.fp is None 25 | except AttributeError: 26 | pass 27 | 28 | raise ValueError("Unable to determine whether fp is closed.") 29 | 30 | 31 | def assert_header_parsing(headers): 32 | """ 33 | Asserts whether all headers have been successfully parsed. 34 | Extracts encountered errors from the result of parsing headers. 35 | 36 | Only works on Python 3. 37 | 38 | :param headers: Headers to verify. 39 | :type headers: `httplib.HTTPMessage`. 40 | 41 | :raises urllib3.exceptions.HeaderParsingError: 42 | If parsing errors are found. 43 | """ 44 | 45 | # This will fail silently if we pass in the wrong kind of parameter. 46 | # To make debugging easier add an explicit check. 47 | if not isinstance(headers, httplib.HTTPMessage): 48 | raise TypeError('expected httplib.Message, got {0}.'.format( 49 | type(headers))) 50 | 51 | defects = getattr(headers, 'defects', None) 52 | get_payload = getattr(headers, 'get_payload', None) 53 | 54 | unparsed_data = None 55 | if get_payload: # Platform-specific: Python 3. 56 | unparsed_data = get_payload() 57 | 58 | if defects or unparsed_data: 59 | raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data) 60 | 61 | 62 | def is_response_to_head(response): 63 | """ 64 | Checks, wether a the request of a response has been a HEAD-request. 65 | Handles the quirks of AppEngine. 66 | 67 | :param conn: 68 | :type conn: :class:`httplib.HTTPResponse` 69 | """ 70 | # FIXME: Can we do this somehow without accessing private httplib _method? 71 | method = response._method 72 | if isinstance(method, int): # Platform-specific: Appengine 73 | return method == 3 74 | return method.upper() == 'HEAD' 75 | -------------------------------------------------------------------------------- /requests/packages/chardet/codingstatemachine.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from .constants import eStart 29 | from .compat import wrap_ord 30 | 31 | 32 | class CodingStateMachine: 33 | def __init__(self, sm): 34 | self._mModel = sm 35 | self._mCurrentBytePos = 0 36 | self._mCurrentCharLen = 0 37 | self.reset() 38 | 39 | def reset(self): 40 | self._mCurrentState = eStart 41 | 42 | def next_state(self, c): 43 | # for each byte we get its class 44 | # if it is first byte, we also get byte length 45 | # PY3K: aBuf is a byte stream, so c is an int, not a byte 46 | byteCls = self._mModel['classTable'][wrap_ord(c)] 47 | if self._mCurrentState == eStart: 48 | self._mCurrentBytePos = 0 49 | self._mCurrentCharLen = self._mModel['charLenTable'][byteCls] 50 | # from byte's class and stateTable, we get its next state 51 | curr_state = (self._mCurrentState * self._mModel['classFactor'] 52 | + byteCls) 53 | self._mCurrentState = self._mModel['stateTable'][curr_state] 54 | self._mCurrentBytePos += 1 55 | return self._mCurrentState 56 | 57 | def get_current_charlen(self): 58 | return self._mCurrentCharLen 59 | 60 | def get_coding_state_machine(self): 61 | return self._mModel['name'] 62 | -------------------------------------------------------------------------------- /requests/packages/urllib3/filepost.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | import codecs 3 | 4 | from uuid import uuid4 5 | from io import BytesIO 6 | 7 | from .packages import six 8 | from .packages.six import b 9 | from .fields import RequestField 10 | 11 | writer = codecs.lookup('utf-8')[3] 12 | 13 | 14 | def choose_boundary(): 15 | """ 16 | Our embarassingly-simple replacement for mimetools.choose_boundary. 17 | """ 18 | return uuid4().hex 19 | 20 | 21 | def iter_field_objects(fields): 22 | """ 23 | Iterate over fields. 24 | 25 | Supports list of (k, v) tuples and dicts, and lists of 26 | :class:`~urllib3.fields.RequestField`. 27 | 28 | """ 29 | if isinstance(fields, dict): 30 | i = six.iteritems(fields) 31 | else: 32 | i = iter(fields) 33 | 34 | for field in i: 35 | if isinstance(field, RequestField): 36 | yield field 37 | else: 38 | yield RequestField.from_tuples(*field) 39 | 40 | 41 | def iter_fields(fields): 42 | """ 43 | .. deprecated:: 1.6 44 | 45 | Iterate over fields. 46 | 47 | The addition of :class:`~urllib3.fields.RequestField` makes this function 48 | obsolete. Instead, use :func:`iter_field_objects`, which returns 49 | :class:`~urllib3.fields.RequestField` objects. 50 | 51 | Supports list of (k, v) tuples and dicts. 52 | """ 53 | if isinstance(fields, dict): 54 | return ((k, v) for k, v in six.iteritems(fields)) 55 | 56 | return ((k, v) for k, v in fields) 57 | 58 | 59 | def encode_multipart_formdata(fields, boundary=None): 60 | """ 61 | Encode a dictionary of ``fields`` using the multipart/form-data MIME format. 62 | 63 | :param fields: 64 | Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`). 65 | 66 | :param boundary: 67 | If not specified, then a random boundary will be generated using 68 | :func:`mimetools.choose_boundary`. 69 | """ 70 | body = BytesIO() 71 | if boundary is None: 72 | boundary = choose_boundary() 73 | 74 | for field in iter_field_objects(fields): 75 | body.write(b('--%s\r\n' % (boundary))) 76 | 77 | writer(body).write(field.render_headers()) 78 | data = field.data 79 | 80 | if isinstance(data, int): 81 | data = str(data) # Backwards compatibility 82 | 83 | if isinstance(data, six.text_type): 84 | writer(body).write(data) 85 | else: 86 | body.write(data) 87 | 88 | body.write(b'\r\n') 89 | 90 | body.write(b('--%s--\r\n' % (boundary))) 91 | 92 | content_type = str('multipart/form-data; boundary=%s' % boundary) 93 | 94 | return body.getvalue(), content_type 95 | -------------------------------------------------------------------------------- /rsa/parallel.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Sybren A. Stüvel 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Functions for parallel computation on multiple cores. 18 | 19 | Introduced in Python-RSA 3.1. 20 | 21 | .. note:: 22 | 23 | Requires Python 2.6 or newer. 24 | 25 | """ 26 | 27 | from __future__ import print_function 28 | 29 | import multiprocessing as mp 30 | 31 | import rsa.prime 32 | import rsa.randnum 33 | 34 | 35 | def _find_prime(nbits, pipe): 36 | while True: 37 | integer = rsa.randnum.read_random_odd_int(nbits) 38 | 39 | # Test for primeness 40 | if rsa.prime.is_prime(integer): 41 | pipe.send(integer) 42 | return 43 | 44 | 45 | def getprime(nbits, poolsize): 46 | """Returns a prime number that can be stored in 'nbits' bits. 47 | 48 | Works in multiple threads at the same time. 49 | 50 | >>> p = getprime(128, 3) 51 | >>> rsa.prime.is_prime(p-1) 52 | False 53 | >>> rsa.prime.is_prime(p) 54 | True 55 | >>> rsa.prime.is_prime(p+1) 56 | False 57 | 58 | >>> from rsa import common 59 | >>> common.bit_size(p) == 128 60 | True 61 | 62 | """ 63 | 64 | (pipe_recv, pipe_send) = mp.Pipe(duplex=False) 65 | 66 | # Create processes 67 | try: 68 | procs = [mp.Process(target=_find_prime, args=(nbits, pipe_send)) 69 | for _ in range(poolsize)] 70 | # Start processes 71 | for p in procs: 72 | p.start() 73 | 74 | result = pipe_recv.recv() 75 | finally: 76 | pipe_recv.close() 77 | pipe_send.close() 78 | 79 | # Terminate processes 80 | for p in procs: 81 | p.terminate() 82 | 83 | return result 84 | 85 | 86 | __all__ = ['getprime'] 87 | 88 | if __name__ == '__main__': 89 | print('Running doctests 1000x or until failure') 90 | import doctest 91 | 92 | for count in range(100): 93 | (failures, tests) = doctest.testmod() 94 | if failures: 95 | break 96 | 97 | if count and count % 10 == 0: 98 | print('%i times' % count) 99 | 100 | print('Doctests done') 101 | -------------------------------------------------------------------------------- /requests/packages/chardet/chardetect.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Script which takes one or more file paths and reports on their detected 4 | encodings 5 | 6 | Example:: 7 | 8 | % chardetect somefile someotherfile 9 | somefile: windows-1252 with confidence 0.5 10 | someotherfile: ascii with confidence 1.0 11 | 12 | If no paths are provided, it takes its input from stdin. 13 | 14 | """ 15 | 16 | from __future__ import absolute_import, print_function, unicode_literals 17 | 18 | import argparse 19 | import sys 20 | from io import open 21 | 22 | from chardet import __version__ 23 | from chardet.universaldetector import UniversalDetector 24 | 25 | 26 | def description_of(lines, name='stdin'): 27 | """ 28 | Return a string describing the probable encoding of a file or 29 | list of strings. 30 | 31 | :param lines: The lines to get the encoding of. 32 | :type lines: Iterable of bytes 33 | :param name: Name of file or collection of lines 34 | :type name: str 35 | """ 36 | u = UniversalDetector() 37 | for line in lines: 38 | u.feed(line) 39 | u.close() 40 | result = u.result 41 | if result['encoding']: 42 | return '{0}: {1} with confidence {2}'.format(name, result['encoding'], 43 | result['confidence']) 44 | else: 45 | return '{0}: no result'.format(name) 46 | 47 | 48 | def main(argv=None): 49 | ''' 50 | Handles command line arguments and gets things started. 51 | 52 | :param argv: List of arguments, as if specified on the command-line. 53 | If None, ``sys.argv[1:]`` is used instead. 54 | :type argv: list of str 55 | ''' 56 | # Get command line arguments 57 | parser = argparse.ArgumentParser( 58 | description="Takes one or more file paths and reports their detected \ 59 | encodings", 60 | formatter_class=argparse.ArgumentDefaultsHelpFormatter, 61 | conflict_handler='resolve') 62 | parser.add_argument('input', 63 | help='File whose encoding we would like to determine.', 64 | type=argparse.FileType('rb'), nargs='*', 65 | default=[sys.stdin]) 66 | parser.add_argument('--version', action='version', 67 | version='%(prog)s {0}'.format(__version__)) 68 | args = parser.parse_args(argv) 69 | 70 | for f in args.input: 71 | if f.isatty(): 72 | print("You are running chardetect interactively. Press " + 73 | "CTRL-D twice at the start of a blank line to signal the " + 74 | "end of your input. If you want help, run chardetect " + 75 | "--help\n", file=sys.stderr) 76 | print(description_of(f, f.name)) 77 | 78 | 79 | if __name__ == '__main__': 80 | main() 81 | -------------------------------------------------------------------------------- /requests/packages/chardet/utf8prober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from . import constants 29 | from .charsetprober import CharSetProber 30 | from .codingstatemachine import CodingStateMachine 31 | from .mbcssm import UTF8SMModel 32 | 33 | ONE_CHAR_PROB = 0.5 34 | 35 | 36 | class UTF8Prober(CharSetProber): 37 | def __init__(self): 38 | CharSetProber.__init__(self) 39 | self._mCodingSM = CodingStateMachine(UTF8SMModel) 40 | self.reset() 41 | 42 | def reset(self): 43 | CharSetProber.reset(self) 44 | self._mCodingSM.reset() 45 | self._mNumOfMBChar = 0 46 | 47 | def get_charset_name(self): 48 | return "utf-8" 49 | 50 | def feed(self, aBuf): 51 | for c in aBuf: 52 | codingState = self._mCodingSM.next_state(c) 53 | if codingState == constants.eError: 54 | self._mState = constants.eNotMe 55 | break 56 | elif codingState == constants.eItsMe: 57 | self._mState = constants.eFoundIt 58 | break 59 | elif codingState == constants.eStart: 60 | if self._mCodingSM.get_current_charlen() >= 2: 61 | self._mNumOfMBChar += 1 62 | 63 | if self.get_state() == constants.eDetecting: 64 | if self.get_confidence() > constants.SHORTCUT_THRESHOLD: 65 | self._mState = constants.eFoundIt 66 | 67 | return self.get_state() 68 | 69 | def get_confidence(self): 70 | unlike = 0.99 71 | if self._mNumOfMBChar < 6: 72 | for i in range(0, self._mNumOfMBChar): 73 | unlike = unlike * ONE_CHAR_PROB 74 | return 1.0 - unlike 75 | else: 76 | return unlike 77 | -------------------------------------------------------------------------------- /rsa/randnum.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Sybren A. Stüvel 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Functions for generating random numbers.""" 18 | 19 | # Source inspired by code by Yesudeep Mangalapilly 20 | 21 | import os 22 | 23 | from rsa import common, transform 24 | from rsa._compat import byte 25 | 26 | 27 | def read_random_bits(nbits): 28 | """Reads 'nbits' random bits. 29 | 30 | If nbits isn't a whole number of bytes, an extra byte will be appended with 31 | only the lower bits set. 32 | """ 33 | 34 | nbytes, rbits = divmod(nbits, 8) 35 | 36 | # Get the random bytes 37 | randomdata = os.urandom(nbytes) 38 | 39 | # Add the remaining random bits 40 | if rbits > 0: 41 | randomvalue = ord(os.urandom(1)) 42 | randomvalue >>= (8 - rbits) 43 | randomdata = byte(randomvalue) + randomdata 44 | 45 | return randomdata 46 | 47 | 48 | def read_random_int(nbits): 49 | """Reads a random integer of approximately nbits bits. 50 | """ 51 | 52 | randomdata = read_random_bits(nbits) 53 | value = transform.bytes2int(randomdata) 54 | 55 | # Ensure that the number is large enough to just fill out the required 56 | # number of bits. 57 | value |= 1 << (nbits - 1) 58 | 59 | return value 60 | 61 | 62 | def read_random_odd_int(nbits): 63 | """Reads a random odd integer of approximately nbits bits. 64 | 65 | >>> read_random_odd_int(512) & 1 66 | 1 67 | """ 68 | 69 | value = read_random_int(nbits) 70 | 71 | # Make sure it's odd 72 | return value | 1 73 | 74 | 75 | def randint(maxvalue): 76 | """Returns a random integer x with 1 <= x <= maxvalue 77 | 78 | May take a very long time in specific situations. If maxvalue needs N bits 79 | to store, the closer maxvalue is to (2 ** N) - 1, the faster this function 80 | is. 81 | """ 82 | 83 | bit_size = common.bit_size(maxvalue) 84 | 85 | tries = 0 86 | while True: 87 | value = read_random_int(bit_size) 88 | if value <= maxvalue: 89 | break 90 | 91 | if tries and tries % 10 == 0: 92 | # After a lot of tries to get the right number of bits but still 93 | # smaller than maxvalue, decrease the number of bits by 1. That'll 94 | # dramatically increase the chances to get a large enough number. 95 | bit_size -= 1 96 | tries += 1 97 | 98 | return value 99 | -------------------------------------------------------------------------------- /requests/packages/urllib3/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | urllib3 - Thread-safe connection pooling and re-using. 3 | """ 4 | 5 | from __future__ import absolute_import 6 | import warnings 7 | 8 | from .connectionpool import ( 9 | HTTPConnectionPool, 10 | HTTPSConnectionPool, 11 | connection_from_url 12 | ) 13 | 14 | from . import exceptions 15 | from .filepost import encode_multipart_formdata 16 | from .poolmanager import PoolManager, ProxyManager, proxy_from_url 17 | from .response import HTTPResponse 18 | from .util.request import make_headers 19 | from .util.url import get_host 20 | from .util.timeout import Timeout 21 | from .util.retry import Retry 22 | 23 | 24 | # Set default logging handler to avoid "No handler found" warnings. 25 | import logging 26 | try: # Python 2.7+ 27 | from logging import NullHandler 28 | except ImportError: 29 | class NullHandler(logging.Handler): 30 | def emit(self, record): 31 | pass 32 | 33 | __author__ = 'Andrey Petrov (andrey.petrov@shazow.net)' 34 | __license__ = 'MIT' 35 | __version__ = '1.13.1' 36 | 37 | __all__ = ( 38 | 'HTTPConnectionPool', 39 | 'HTTPSConnectionPool', 40 | 'PoolManager', 41 | 'ProxyManager', 42 | 'HTTPResponse', 43 | 'Retry', 44 | 'Timeout', 45 | 'add_stderr_logger', 46 | 'connection_from_url', 47 | 'disable_warnings', 48 | 'encode_multipart_formdata', 49 | 'get_host', 50 | 'make_headers', 51 | 'proxy_from_url', 52 | ) 53 | 54 | logging.getLogger(__name__).addHandler(NullHandler()) 55 | 56 | 57 | def add_stderr_logger(level=logging.DEBUG): 58 | """ 59 | Helper for quickly adding a StreamHandler to the logger. Useful for 60 | debugging. 61 | 62 | Returns the handler after adding it. 63 | """ 64 | # This method needs to be in this __init__.py to get the __name__ correct 65 | # even if urllib3 is vendored within another package. 66 | logger = logging.getLogger(__name__) 67 | handler = logging.StreamHandler() 68 | handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s')) 69 | logger.addHandler(handler) 70 | logger.setLevel(level) 71 | logger.debug('Added a stderr logging handler to logger: %s' % __name__) 72 | return handler 73 | 74 | # ... Clean up. 75 | del NullHandler 76 | 77 | 78 | # SecurityWarning's always go off by default. 79 | warnings.simplefilter('always', exceptions.SecurityWarning, append=True) 80 | # SubjectAltNameWarning's should go off once per host 81 | warnings.simplefilter('default', exceptions.SubjectAltNameWarning) 82 | # InsecurePlatformWarning's don't vary between requests, so we keep it default. 83 | warnings.simplefilter('default', exceptions.InsecurePlatformWarning, 84 | append=True) 85 | # SNIMissingWarnings should go off only once. 86 | warnings.simplefilter('default', exceptions.SNIMissingWarning) 87 | 88 | 89 | def disable_warnings(category=exceptions.HTTPWarning): 90 | """ 91 | Helper for quickly disabling all urllib3 warnings. 92 | """ 93 | warnings.simplefilter('ignore', category) 94 | -------------------------------------------------------------------------------- /clipboard.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # vim:fenc=utf-8 4 | # 5 | # Copyright © 2016 ciel 6 | # 7 | # Distributed under terms of the MIT license. 8 | 9 | """ 10 | 将剪切板中的文件拷贝到临时目录并返回临时目录中的图片 11 | """ 12 | 13 | import os 14 | import tempfile 15 | import imghdr 16 | import shutil 17 | 18 | from AppKit import NSPasteboard, NSPasteboardTypePNG,\ 19 | NSPasteboardTypeTIFF, NSPasteboardTypeString,\ 20 | NSFilenamesPboardType 21 | 22 | def _convert_to_png(from_path, to_path): 23 | # convert it to png file 24 | os.system('sips -s format png %s --out %s' % (from_path, to_path)) 25 | 26 | def get_paste_img_file(): 27 | ''' get a img file from clipboard; 28 | the return object is a `tempfile.NamedTemporaryFile` 29 | you can use the name field to access the file path. 30 | the tmp file will be delete as soon as possible(when gc happened or close explicitly) 31 | you can not just return a path, must hold the reference''' 32 | 33 | pb = NSPasteboard.generalPasteboard() 34 | data_type = pb.types() 35 | 36 | supported_image_format = (NSPasteboardTypePNG, NSPasteboardTypeTIFF) 37 | if NSFilenamesPboardType in data_type: 38 | # file in clipboard 39 | img_path = pb.propertyListForType_(NSFilenamesPboardType)[0] 40 | img_type = imghdr.what(img_path) 41 | 42 | if not img_type: 43 | # not image file 44 | return None 45 | 46 | if img_type not in ('png', 'jpeg', 'gif'): 47 | # now only support png & jpg & gif 48 | return None 49 | 50 | is_gif = img_type == 'gif' 51 | _file = tempfile.NamedTemporaryFile(suffix=img_type) 52 | tmp_clipboard_img_file = tempfile.NamedTemporaryFile() 53 | shutil.copy(img_path, tmp_clipboard_img_file.name) 54 | if not is_gif: 55 | _convert_to_png(tmp_clipboard_img_file.name, _file.name) 56 | else: 57 | shutil.copy(tmp_clipboard_img_file.name, _file.name) 58 | tmp_clipboard_img_file.close() 59 | return _file 60 | 61 | if NSPasteboardTypeString in data_type: 62 | # make this be first, because plain text may be TIFF format? 63 | # string todo, recognise url of png & jpg 64 | pass 65 | 66 | if any(filter(lambda f: f in data_type, supported_image_format)): 67 | # do not care which format it is, we convert it to png finally 68 | # system screen shotcut is png, QQ is tiff 69 | tmp_clipboard_img_file = tempfile.NamedTemporaryFile() 70 | print tmp_clipboard_img_file.name 71 | png_file = tempfile.NamedTemporaryFile(suffix='png') 72 | for fmt in supported_image_format: 73 | data = pb.dataForType_(fmt) 74 | if data: 75 | break 76 | ret = data.writeToFile_atomically_(tmp_clipboard_img_file.name, False) 77 | if not ret: 78 | return None 79 | 80 | _convert_to_png(tmp_clipboard_img_file.name, png_file.name) 81 | # close the file explicitly 82 | tmp_clipboard_img_file.close() 83 | return png_file 84 | 85 | if __name__ == '__main__': 86 | get_paste_img_file() 87 | -------------------------------------------------------------------------------- /rsa/util.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Sybren A. Stüvel 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Utility functions.""" 18 | 19 | from __future__ import with_statement, print_function 20 | 21 | import sys 22 | from optparse import OptionParser 23 | 24 | import rsa.key 25 | 26 | 27 | def private_to_public(): 28 | """Reads a private key and outputs the corresponding public key.""" 29 | 30 | # Parse the CLI options 31 | parser = OptionParser(usage='usage: %prog [options]', 32 | description='Reads a private key and outputs the ' 33 | 'corresponding public key. Both private and public keys use ' 34 | 'the format described in PKCS#1 v1.5') 35 | 36 | parser.add_option('-i', '--input', dest='infilename', type='string', 37 | help='Input filename. Reads from stdin if not specified') 38 | parser.add_option('-o', '--output', dest='outfilename', type='string', 39 | help='Output filename. Writes to stdout of not specified') 40 | 41 | parser.add_option('--inform', dest='inform', 42 | help='key format of input - default PEM', 43 | choices=('PEM', 'DER'), default='PEM') 44 | 45 | parser.add_option('--outform', dest='outform', 46 | help='key format of output - default PEM', 47 | choices=('PEM', 'DER'), default='PEM') 48 | 49 | (cli, cli_args) = parser.parse_args(sys.argv) 50 | 51 | # Read the input data 52 | if cli.infilename: 53 | print('Reading private key from %s in %s format' % 54 | (cli.infilename, cli.inform), file=sys.stderr) 55 | with open(cli.infilename, 'rb') as infile: 56 | in_data = infile.read() 57 | else: 58 | print('Reading private key from stdin in %s format' % cli.inform, 59 | file=sys.stderr) 60 | in_data = sys.stdin.read().encode('ascii') 61 | 62 | assert type(in_data) == bytes, type(in_data) 63 | 64 | # Take the public fields and create a public key 65 | priv_key = rsa.key.PrivateKey.load_pkcs1(in_data, cli.inform) 66 | pub_key = rsa.key.PublicKey(priv_key.n, priv_key.e) 67 | 68 | # Save to the output file 69 | out_data = pub_key.save_pkcs1(cli.outform) 70 | 71 | if cli.outfilename: 72 | print('Writing public key to %s in %s format' % 73 | (cli.outfilename, cli.outform), file=sys.stderr) 74 | with open(cli.outfilename, 'wb') as outfile: 75 | outfile.write(out_data) 76 | else: 77 | print('Writing public key to stdout in %s format' % cli.outform, 78 | file=sys.stderr) 79 | sys.stdout.write(out_data.decode('ascii')) 80 | -------------------------------------------------------------------------------- /requests/exceptions.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | requests.exceptions 5 | ~~~~~~~~~~~~~~~~~~~ 6 | 7 | This module contains the set of Requests' exceptions. 8 | 9 | """ 10 | from .packages.urllib3.exceptions import HTTPError as BaseHTTPError 11 | 12 | 13 | class RequestException(IOError): 14 | """There was an ambiguous exception that occurred while handling your 15 | request.""" 16 | 17 | def __init__(self, *args, **kwargs): 18 | """ 19 | Initialize RequestException with `request` and `response` objects. 20 | """ 21 | response = kwargs.pop('response', None) 22 | self.response = response 23 | self.request = kwargs.pop('request', None) 24 | if (response is not None and not self.request and 25 | hasattr(response, 'request')): 26 | self.request = self.response.request 27 | super(RequestException, self).__init__(*args, **kwargs) 28 | 29 | 30 | class HTTPError(RequestException): 31 | """An HTTP error occurred.""" 32 | 33 | 34 | class ConnectionError(RequestException): 35 | """A Connection error occurred.""" 36 | 37 | 38 | class ProxyError(ConnectionError): 39 | """A proxy error occurred.""" 40 | 41 | 42 | class SSLError(ConnectionError): 43 | """An SSL error occurred.""" 44 | 45 | 46 | class Timeout(RequestException): 47 | """The request timed out. 48 | 49 | Catching this error will catch both 50 | :exc:`~requests.exceptions.ConnectTimeout` and 51 | :exc:`~requests.exceptions.ReadTimeout` errors. 52 | """ 53 | 54 | 55 | class ConnectTimeout(ConnectionError, Timeout): 56 | """The request timed out while trying to connect to the remote server. 57 | 58 | Requests that produced this error are safe to retry. 59 | """ 60 | 61 | 62 | class ReadTimeout(Timeout): 63 | """The server did not send any data in the allotted amount of time.""" 64 | 65 | 66 | class URLRequired(RequestException): 67 | """A valid URL is required to make a request.""" 68 | 69 | 70 | class TooManyRedirects(RequestException): 71 | """Too many redirects.""" 72 | 73 | 74 | class MissingSchema(RequestException, ValueError): 75 | """The URL schema (e.g. http or https) is missing.""" 76 | 77 | 78 | class InvalidSchema(RequestException, ValueError): 79 | """See defaults.py for valid schemas.""" 80 | 81 | 82 | class InvalidURL(RequestException, ValueError): 83 | """ The URL provided was somehow invalid. """ 84 | 85 | 86 | class ChunkedEncodingError(RequestException): 87 | """The server declared chunked encoding but sent an invalid chunk.""" 88 | 89 | 90 | class ContentDecodingError(RequestException, BaseHTTPError): 91 | """Failed to decode response content""" 92 | 93 | 94 | class StreamConsumedError(RequestException, TypeError): 95 | """The content for this response was already consumed""" 96 | 97 | 98 | class RetryError(RequestException): 99 | """Custom retries logic failed""" 100 | 101 | 102 | # Warnings 103 | 104 | 105 | class RequestsWarning(Warning): 106 | """Base warning for Requests.""" 107 | pass 108 | 109 | 110 | class FileModeWarning(RequestsWarning, DeprecationWarning): 111 | """ 112 | A file was opened in text mode, but Requests determined its binary length. 113 | """ 114 | pass 115 | -------------------------------------------------------------------------------- /requests/structures.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | requests.structures 5 | ~~~~~~~~~~~~~~~~~~~ 6 | 7 | Data structures that power Requests. 8 | 9 | """ 10 | 11 | import collections 12 | 13 | 14 | class CaseInsensitiveDict(collections.MutableMapping): 15 | """ 16 | A case-insensitive ``dict``-like object. 17 | 18 | Implements all methods and operations of 19 | ``collections.MutableMapping`` as well as dict's ``copy``. Also 20 | provides ``lower_items``. 21 | 22 | All keys are expected to be strings. The structure remembers the 23 | case of the last key to be set, and ``iter(instance)``, 24 | ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()`` 25 | will contain case-sensitive keys. However, querying and contains 26 | testing is case insensitive:: 27 | 28 | cid = CaseInsensitiveDict() 29 | cid['Accept'] = 'application/json' 30 | cid['aCCEPT'] == 'application/json' # True 31 | list(cid) == ['Accept'] # True 32 | 33 | For example, ``headers['content-encoding']`` will return the 34 | value of a ``'Content-Encoding'`` response header, regardless 35 | of how the header name was originally stored. 36 | 37 | If the constructor, ``.update``, or equality comparison 38 | operations are given keys that have equal ``.lower()``s, the 39 | behavior is undefined. 40 | 41 | """ 42 | def __init__(self, data=None, **kwargs): 43 | self._store = dict() 44 | if data is None: 45 | data = {} 46 | self.update(data, **kwargs) 47 | 48 | def __setitem__(self, key, value): 49 | # Use the lowercased key for lookups, but store the actual 50 | # key alongside the value. 51 | self._store[key.lower()] = (key, value) 52 | 53 | def __getitem__(self, key): 54 | return self._store[key.lower()][1] 55 | 56 | def __delitem__(self, key): 57 | del self._store[key.lower()] 58 | 59 | def __iter__(self): 60 | return (casedkey for casedkey, mappedvalue in self._store.values()) 61 | 62 | def __len__(self): 63 | return len(self._store) 64 | 65 | def lower_items(self): 66 | """Like iteritems(), but with all lowercase keys.""" 67 | return ( 68 | (lowerkey, keyval[1]) 69 | for (lowerkey, keyval) 70 | in self._store.items() 71 | ) 72 | 73 | def __eq__(self, other): 74 | if isinstance(other, collections.Mapping): 75 | other = CaseInsensitiveDict(other) 76 | else: 77 | return NotImplemented 78 | # Compare insensitively 79 | return dict(self.lower_items()) == dict(other.lower_items()) 80 | 81 | # Copy is required 82 | def copy(self): 83 | return CaseInsensitiveDict(self._store.values()) 84 | 85 | def __repr__(self): 86 | return str(dict(self.items())) 87 | 88 | class LookupDict(dict): 89 | """Dictionary lookup object.""" 90 | 91 | def __init__(self, name=None): 92 | self.name = name 93 | super(LookupDict, self).__init__() 94 | 95 | def __repr__(self): 96 | return '' % (self.name) 97 | 98 | def __getitem__(self, key): 99 | # We allow fall-through here, so values default to None 100 | 101 | return self.__dict__.get(key, None) 102 | 103 | def get(self, key, default=None): 104 | return self.__dict__.get(key, default) 105 | -------------------------------------------------------------------------------- /requests/packages/chardet/escprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from . import constants 29 | from .escsm import (HZSMModel, ISO2022CNSMModel, ISO2022JPSMModel, 30 | ISO2022KRSMModel) 31 | from .charsetprober import CharSetProber 32 | from .codingstatemachine import CodingStateMachine 33 | from .compat import wrap_ord 34 | 35 | 36 | class EscCharSetProber(CharSetProber): 37 | def __init__(self): 38 | CharSetProber.__init__(self) 39 | self._mCodingSM = [ 40 | CodingStateMachine(HZSMModel), 41 | CodingStateMachine(ISO2022CNSMModel), 42 | CodingStateMachine(ISO2022JPSMModel), 43 | CodingStateMachine(ISO2022KRSMModel) 44 | ] 45 | self.reset() 46 | 47 | def reset(self): 48 | CharSetProber.reset(self) 49 | for codingSM in self._mCodingSM: 50 | if not codingSM: 51 | continue 52 | codingSM.active = True 53 | codingSM.reset() 54 | self._mActiveSM = len(self._mCodingSM) 55 | self._mDetectedCharset = None 56 | 57 | def get_charset_name(self): 58 | return self._mDetectedCharset 59 | 60 | def get_confidence(self): 61 | if self._mDetectedCharset: 62 | return 0.99 63 | else: 64 | return 0.00 65 | 66 | def feed(self, aBuf): 67 | for c in aBuf: 68 | # PY3K: aBuf is a byte array, so c is an int, not a byte 69 | for codingSM in self._mCodingSM: 70 | if not codingSM: 71 | continue 72 | if not codingSM.active: 73 | continue 74 | codingState = codingSM.next_state(wrap_ord(c)) 75 | if codingState == constants.eError: 76 | codingSM.active = False 77 | self._mActiveSM -= 1 78 | if self._mActiveSM <= 0: 79 | self._mState = constants.eNotMe 80 | return self.get_state() 81 | elif codingState == constants.eItsMe: 82 | self._mState = constants.eFoundIt 83 | self._mDetectedCharset = codingSM.get_coding_state_machine() # nopep8 84 | return self.get_state() 85 | 86 | return self.get_state() 87 | -------------------------------------------------------------------------------- /requests/packages/chardet/sbcsgroupprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Universal charset detector code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 2001 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # Shy Shalom - original C code 12 | # 13 | # This library is free software; you can redistribute it and/or 14 | # modify it under the terms of the GNU Lesser General Public 15 | # License as published by the Free Software Foundation; either 16 | # version 2.1 of the License, or (at your option) any later version. 17 | # 18 | # This library is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | # Lesser General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Lesser General Public 24 | # License along with this library; if not, write to the Free Software 25 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 26 | # 02110-1301 USA 27 | ######################### END LICENSE BLOCK ######################### 28 | 29 | from .charsetgroupprober import CharSetGroupProber 30 | from .sbcharsetprober import SingleByteCharSetProber 31 | from .langcyrillicmodel import (Win1251CyrillicModel, Koi8rModel, 32 | Latin5CyrillicModel, MacCyrillicModel, 33 | Ibm866Model, Ibm855Model) 34 | from .langgreekmodel import Latin7GreekModel, Win1253GreekModel 35 | from .langbulgarianmodel import Latin5BulgarianModel, Win1251BulgarianModel 36 | from .langhungarianmodel import Latin2HungarianModel, Win1250HungarianModel 37 | from .langthaimodel import TIS620ThaiModel 38 | from .langhebrewmodel import Win1255HebrewModel 39 | from .hebrewprober import HebrewProber 40 | 41 | 42 | class SBCSGroupProber(CharSetGroupProber): 43 | def __init__(self): 44 | CharSetGroupProber.__init__(self) 45 | self._mProbers = [ 46 | SingleByteCharSetProber(Win1251CyrillicModel), 47 | SingleByteCharSetProber(Koi8rModel), 48 | SingleByteCharSetProber(Latin5CyrillicModel), 49 | SingleByteCharSetProber(MacCyrillicModel), 50 | SingleByteCharSetProber(Ibm866Model), 51 | SingleByteCharSetProber(Ibm855Model), 52 | SingleByteCharSetProber(Latin7GreekModel), 53 | SingleByteCharSetProber(Win1253GreekModel), 54 | SingleByteCharSetProber(Latin5BulgarianModel), 55 | SingleByteCharSetProber(Win1251BulgarianModel), 56 | SingleByteCharSetProber(Latin2HungarianModel), 57 | SingleByteCharSetProber(Win1250HungarianModel), 58 | SingleByteCharSetProber(TIS620ThaiModel), 59 | ] 60 | hebrewProber = HebrewProber() 61 | logicalHebrewProber = SingleByteCharSetProber(Win1255HebrewModel, 62 | False, hebrewProber) 63 | visualHebrewProber = SingleByteCharSetProber(Win1255HebrewModel, True, 64 | hebrewProber) 65 | hebrewProber.set_model_probers(logicalHebrewProber, visualHebrewProber) 66 | self._mProbers.extend([hebrewProber, logicalHebrewProber, 67 | visualHebrewProber]) 68 | 69 | self.reset() 70 | -------------------------------------------------------------------------------- /requests/packages/chardet/mbcharsetprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Universal charset detector code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 2001 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # Shy Shalom - original C code 12 | # Proofpoint, Inc. 13 | # 14 | # This library is free software; you can redistribute it and/or 15 | # modify it under the terms of the GNU Lesser General Public 16 | # License as published by the Free Software Foundation; either 17 | # version 2.1 of the License, or (at your option) any later version. 18 | # 19 | # This library is distributed in the hope that it will be useful, 20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 | # Lesser General Public License for more details. 23 | # 24 | # You should have received a copy of the GNU Lesser General Public 25 | # License along with this library; if not, write to the Free Software 26 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 27 | # 02110-1301 USA 28 | ######################### END LICENSE BLOCK ######################### 29 | 30 | import sys 31 | from . import constants 32 | from .charsetprober import CharSetProber 33 | 34 | 35 | class MultiByteCharSetProber(CharSetProber): 36 | def __init__(self): 37 | CharSetProber.__init__(self) 38 | self._mDistributionAnalyzer = None 39 | self._mCodingSM = None 40 | self._mLastChar = [0, 0] 41 | 42 | def reset(self): 43 | CharSetProber.reset(self) 44 | if self._mCodingSM: 45 | self._mCodingSM.reset() 46 | if self._mDistributionAnalyzer: 47 | self._mDistributionAnalyzer.reset() 48 | self._mLastChar = [0, 0] 49 | 50 | def get_charset_name(self): 51 | pass 52 | 53 | def feed(self, aBuf): 54 | aLen = len(aBuf) 55 | for i in range(0, aLen): 56 | codingState = self._mCodingSM.next_state(aBuf[i]) 57 | if codingState == constants.eError: 58 | if constants._debug: 59 | sys.stderr.write(self.get_charset_name() 60 | + ' prober hit error at byte ' + str(i) 61 | + '\n') 62 | self._mState = constants.eNotMe 63 | break 64 | elif codingState == constants.eItsMe: 65 | self._mState = constants.eFoundIt 66 | break 67 | elif codingState == constants.eStart: 68 | charLen = self._mCodingSM.get_current_charlen() 69 | if i == 0: 70 | self._mLastChar[1] = aBuf[0] 71 | self._mDistributionAnalyzer.feed(self._mLastChar, charLen) 72 | else: 73 | self._mDistributionAnalyzer.feed(aBuf[i - 1:i + 1], 74 | charLen) 75 | 76 | self._mLastChar[0] = aBuf[aLen - 1] 77 | 78 | if self.get_state() == constants.eDetecting: 79 | if (self._mDistributionAnalyzer.got_enough_data() and 80 | (self.get_confidence() > constants.SHORTCUT_THRESHOLD)): 81 | self._mState = constants.eFoundIt 82 | 83 | return self.get_state() 84 | 85 | def get_confidence(self): 86 | return self._mDistributionAnalyzer.get_confidence() 87 | -------------------------------------------------------------------------------- /requests/status_codes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from .structures import LookupDict 4 | 5 | _codes = { 6 | 7 | # Informational. 8 | 100: ('continue',), 9 | 101: ('switching_protocols',), 10 | 102: ('processing',), 11 | 103: ('checkpoint',), 12 | 122: ('uri_too_long', 'request_uri_too_long'), 13 | 200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'), 14 | 201: ('created',), 15 | 202: ('accepted',), 16 | 203: ('non_authoritative_info', 'non_authoritative_information'), 17 | 204: ('no_content',), 18 | 205: ('reset_content', 'reset'), 19 | 206: ('partial_content', 'partial'), 20 | 207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'), 21 | 208: ('already_reported',), 22 | 226: ('im_used',), 23 | 24 | # Redirection. 25 | 300: ('multiple_choices',), 26 | 301: ('moved_permanently', 'moved', '\\o-'), 27 | 302: ('found',), 28 | 303: ('see_other', 'other'), 29 | 304: ('not_modified',), 30 | 305: ('use_proxy',), 31 | 306: ('switch_proxy',), 32 | 307: ('temporary_redirect', 'temporary_moved', 'temporary'), 33 | 308: ('permanent_redirect', 34 | 'resume_incomplete', 'resume',), # These 2 to be removed in 3.0 35 | 36 | # Client Error. 37 | 400: ('bad_request', 'bad'), 38 | 401: ('unauthorized',), 39 | 402: ('payment_required', 'payment'), 40 | 403: ('forbidden',), 41 | 404: ('not_found', '-o-'), 42 | 405: ('method_not_allowed', 'not_allowed'), 43 | 406: ('not_acceptable',), 44 | 407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'), 45 | 408: ('request_timeout', 'timeout'), 46 | 409: ('conflict',), 47 | 410: ('gone',), 48 | 411: ('length_required',), 49 | 412: ('precondition_failed', 'precondition'), 50 | 413: ('request_entity_too_large',), 51 | 414: ('request_uri_too_large',), 52 | 415: ('unsupported_media_type', 'unsupported_media', 'media_type'), 53 | 416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'), 54 | 417: ('expectation_failed',), 55 | 418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'), 56 | 422: ('unprocessable_entity', 'unprocessable'), 57 | 423: ('locked',), 58 | 424: ('failed_dependency', 'dependency'), 59 | 425: ('unordered_collection', 'unordered'), 60 | 426: ('upgrade_required', 'upgrade'), 61 | 428: ('precondition_required', 'precondition'), 62 | 429: ('too_many_requests', 'too_many'), 63 | 431: ('header_fields_too_large', 'fields_too_large'), 64 | 444: ('no_response', 'none'), 65 | 449: ('retry_with', 'retry'), 66 | 450: ('blocked_by_windows_parental_controls', 'parental_controls'), 67 | 451: ('unavailable_for_legal_reasons', 'legal_reasons'), 68 | 499: ('client_closed_request',), 69 | 70 | # Server Error. 71 | 500: ('internal_server_error', 'server_error', '/o\\', '✗'), 72 | 501: ('not_implemented',), 73 | 502: ('bad_gateway',), 74 | 503: ('service_unavailable', 'unavailable'), 75 | 504: ('gateway_timeout',), 76 | 505: ('http_version_not_supported', 'http_version'), 77 | 506: ('variant_also_negotiates',), 78 | 507: ('insufficient_storage',), 79 | 509: ('bandwidth_limit_exceeded', 'bandwidth'), 80 | 510: ('not_extended',), 81 | 511: ('network_authentication_required', 'network_auth', 'network_authentication'), 82 | } 83 | 84 | codes = LookupDict(name='status_codes') 85 | 86 | for code, titles in _codes.items(): 87 | for title in titles: 88 | setattr(codes, title, code) 89 | if not title.startswith('\\'): 90 | setattr(codes, title.upper(), code) 91 | -------------------------------------------------------------------------------- /requests/packages/urllib3/util/connection.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | import socket 3 | try: 4 | from select import poll, POLLIN 5 | except ImportError: # `poll` doesn't exist on OSX and other platforms 6 | poll = False 7 | try: 8 | from select import select 9 | except ImportError: # `select` doesn't exist on AppEngine. 10 | select = False 11 | 12 | 13 | def is_connection_dropped(conn): # Platform-specific 14 | """ 15 | Returns True if the connection is dropped and should be closed. 16 | 17 | :param conn: 18 | :class:`httplib.HTTPConnection` object. 19 | 20 | Note: For platforms like AppEngine, this will always return ``False`` to 21 | let the platform handle connection recycling transparently for us. 22 | """ 23 | sock = getattr(conn, 'sock', False) 24 | if sock is False: # Platform-specific: AppEngine 25 | return False 26 | if sock is None: # Connection already closed (such as by httplib). 27 | return True 28 | 29 | if not poll: 30 | if not select: # Platform-specific: AppEngine 31 | return False 32 | 33 | try: 34 | return select([sock], [], [], 0.0)[0] 35 | except socket.error: 36 | return True 37 | 38 | # This version is better on platforms that support it. 39 | p = poll() 40 | p.register(sock, POLLIN) 41 | for (fno, ev) in p.poll(0.0): 42 | if fno == sock.fileno(): 43 | # Either data is buffered (bad), or the connection is dropped. 44 | return True 45 | 46 | 47 | # This function is copied from socket.py in the Python 2.7 standard 48 | # library test suite. Added to its signature is only `socket_options`. 49 | def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, 50 | source_address=None, socket_options=None): 51 | """Connect to *address* and return the socket object. 52 | 53 | Convenience function. Connect to *address* (a 2-tuple ``(host, 54 | port)``) and return the socket object. Passing the optional 55 | *timeout* parameter will set the timeout on the socket instance 56 | before attempting to connect. If no *timeout* is supplied, the 57 | global default timeout setting returned by :func:`getdefaulttimeout` 58 | is used. If *source_address* is set it must be a tuple of (host, port) 59 | for the socket to bind as a source address before making the connection. 60 | An host of '' or port 0 tells the OS to use the default. 61 | """ 62 | 63 | host, port = address 64 | if host.startswith('['): 65 | host = host.strip('[]') 66 | err = None 67 | for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM): 68 | af, socktype, proto, canonname, sa = res 69 | sock = None 70 | try: 71 | sock = socket.socket(af, socktype, proto) 72 | 73 | # If provided, set socket level options before connecting. 74 | # This is the only addition urllib3 makes to this function. 75 | _set_socket_options(sock, socket_options) 76 | 77 | if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: 78 | sock.settimeout(timeout) 79 | if source_address: 80 | sock.bind(source_address) 81 | sock.connect(sa) 82 | return sock 83 | 84 | except socket.error as e: 85 | err = e 86 | if sock is not None: 87 | sock.close() 88 | sock = None 89 | 90 | if err is not None: 91 | raise err 92 | 93 | raise socket.error("getaddrinfo returns an empty list") 94 | 95 | 96 | def _set_socket_options(sock, options): 97 | if options is None: 98 | return 99 | 100 | for opt in options: 101 | sock.setsockopt(*opt) 102 | -------------------------------------------------------------------------------- /requests/packages/chardet/eucjpprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | import sys 29 | from . import constants 30 | from .mbcharsetprober import MultiByteCharSetProber 31 | from .codingstatemachine import CodingStateMachine 32 | from .chardistribution import EUCJPDistributionAnalysis 33 | from .jpcntx import EUCJPContextAnalysis 34 | from .mbcssm import EUCJPSMModel 35 | 36 | 37 | class EUCJPProber(MultiByteCharSetProber): 38 | def __init__(self): 39 | MultiByteCharSetProber.__init__(self) 40 | self._mCodingSM = CodingStateMachine(EUCJPSMModel) 41 | self._mDistributionAnalyzer = EUCJPDistributionAnalysis() 42 | self._mContextAnalyzer = EUCJPContextAnalysis() 43 | self.reset() 44 | 45 | def reset(self): 46 | MultiByteCharSetProber.reset(self) 47 | self._mContextAnalyzer.reset() 48 | 49 | def get_charset_name(self): 50 | return "EUC-JP" 51 | 52 | def feed(self, aBuf): 53 | aLen = len(aBuf) 54 | for i in range(0, aLen): 55 | # PY3K: aBuf is a byte array, so aBuf[i] is an int, not a byte 56 | codingState = self._mCodingSM.next_state(aBuf[i]) 57 | if codingState == constants.eError: 58 | if constants._debug: 59 | sys.stderr.write(self.get_charset_name() 60 | + ' prober hit error at byte ' + str(i) 61 | + '\n') 62 | self._mState = constants.eNotMe 63 | break 64 | elif codingState == constants.eItsMe: 65 | self._mState = constants.eFoundIt 66 | break 67 | elif codingState == constants.eStart: 68 | charLen = self._mCodingSM.get_current_charlen() 69 | if i == 0: 70 | self._mLastChar[1] = aBuf[0] 71 | self._mContextAnalyzer.feed(self._mLastChar, charLen) 72 | self._mDistributionAnalyzer.feed(self._mLastChar, charLen) 73 | else: 74 | self._mContextAnalyzer.feed(aBuf[i - 1:i + 1], charLen) 75 | self._mDistributionAnalyzer.feed(aBuf[i - 1:i + 1], 76 | charLen) 77 | 78 | self._mLastChar[0] = aBuf[aLen - 1] 79 | 80 | if self.get_state() == constants.eDetecting: 81 | if (self._mContextAnalyzer.got_enough_data() and 82 | (self.get_confidence() > constants.SHORTCUT_THRESHOLD)): 83 | self._mState = constants.eFoundIt 84 | 85 | return self.get_state() 86 | 87 | def get_confidence(self): 88 | contxtCf = self._mContextAnalyzer.get_confidence() 89 | distribCf = self._mDistributionAnalyzer.get_confidence() 90 | return max(contxtCf, distribCf) 91 | -------------------------------------------------------------------------------- /requests/packages/chardet/sjisprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | import sys 29 | from .mbcharsetprober import MultiByteCharSetProber 30 | from .codingstatemachine import CodingStateMachine 31 | from .chardistribution import SJISDistributionAnalysis 32 | from .jpcntx import SJISContextAnalysis 33 | from .mbcssm import SJISSMModel 34 | from . import constants 35 | 36 | 37 | class SJISProber(MultiByteCharSetProber): 38 | def __init__(self): 39 | MultiByteCharSetProber.__init__(self) 40 | self._mCodingSM = CodingStateMachine(SJISSMModel) 41 | self._mDistributionAnalyzer = SJISDistributionAnalysis() 42 | self._mContextAnalyzer = SJISContextAnalysis() 43 | self.reset() 44 | 45 | def reset(self): 46 | MultiByteCharSetProber.reset(self) 47 | self._mContextAnalyzer.reset() 48 | 49 | def get_charset_name(self): 50 | return self._mContextAnalyzer.get_charset_name() 51 | 52 | def feed(self, aBuf): 53 | aLen = len(aBuf) 54 | for i in range(0, aLen): 55 | codingState = self._mCodingSM.next_state(aBuf[i]) 56 | if codingState == constants.eError: 57 | if constants._debug: 58 | sys.stderr.write(self.get_charset_name() 59 | + ' prober hit error at byte ' + str(i) 60 | + '\n') 61 | self._mState = constants.eNotMe 62 | break 63 | elif codingState == constants.eItsMe: 64 | self._mState = constants.eFoundIt 65 | break 66 | elif codingState == constants.eStart: 67 | charLen = self._mCodingSM.get_current_charlen() 68 | if i == 0: 69 | self._mLastChar[1] = aBuf[0] 70 | self._mContextAnalyzer.feed(self._mLastChar[2 - charLen:], 71 | charLen) 72 | self._mDistributionAnalyzer.feed(self._mLastChar, charLen) 73 | else: 74 | self._mContextAnalyzer.feed(aBuf[i + 1 - charLen:i + 3 75 | - charLen], charLen) 76 | self._mDistributionAnalyzer.feed(aBuf[i - 1:i + 1], 77 | charLen) 78 | 79 | self._mLastChar[0] = aBuf[aLen - 1] 80 | 81 | if self.get_state() == constants.eDetecting: 82 | if (self._mContextAnalyzer.got_enough_data() and 83 | (self.get_confidence() > constants.SHORTCUT_THRESHOLD)): 84 | self._mState = constants.eFoundIt 85 | 86 | return self.get_state() 87 | 88 | def get_confidence(self): 89 | contxtCf = self._mContextAnalyzer.get_confidence() 90 | distribCf = self._mDistributionAnalyzer.get_confidence() 91 | return max(contxtCf, distribCf) 92 | -------------------------------------------------------------------------------- /rsa/pem.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Sybren A. Stüvel 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Functions that load and write PEM-encoded files.""" 18 | 19 | import base64 20 | from rsa._compat import b, is_bytes 21 | 22 | 23 | def _markers(pem_marker): 24 | """ 25 | Returns the start and end PEM markers 26 | """ 27 | 28 | if is_bytes(pem_marker): 29 | pem_marker = pem_marker.decode('utf-8') 30 | 31 | return (b('-----BEGIN %s-----' % pem_marker), 32 | b('-----END %s-----' % pem_marker)) 33 | 34 | 35 | def load_pem(contents, pem_marker): 36 | """Loads a PEM file. 37 | 38 | :param contents: the contents of the file to interpret 39 | :param pem_marker: the marker of the PEM content, such as 'RSA PRIVATE KEY' 40 | when your file has '-----BEGIN RSA PRIVATE KEY-----' and 41 | '-----END RSA PRIVATE KEY-----' markers. 42 | 43 | :return: the base64-decoded content between the start and end markers. 44 | 45 | @raise ValueError: when the content is invalid, for example when the start 46 | marker cannot be found. 47 | 48 | """ 49 | 50 | # We want bytes, not text. If it's text, it can be converted to ASCII bytes. 51 | if not is_bytes(contents): 52 | contents = contents.encode('ascii') 53 | 54 | (pem_start, pem_end) = _markers(pem_marker) 55 | 56 | pem_lines = [] 57 | in_pem_part = False 58 | 59 | for line in contents.splitlines(): 60 | line = line.strip() 61 | 62 | # Skip empty lines 63 | if not line: 64 | continue 65 | 66 | # Handle start marker 67 | if line == pem_start: 68 | if in_pem_part: 69 | raise ValueError('Seen start marker "%s" twice' % pem_start) 70 | 71 | in_pem_part = True 72 | continue 73 | 74 | # Skip stuff before first marker 75 | if not in_pem_part: 76 | continue 77 | 78 | # Handle end marker 79 | if in_pem_part and line == pem_end: 80 | in_pem_part = False 81 | break 82 | 83 | # Load fields 84 | if b(':') in line: 85 | continue 86 | 87 | pem_lines.append(line) 88 | 89 | # Do some sanity checks 90 | if not pem_lines: 91 | raise ValueError('No PEM start marker "%s" found' % pem_start) 92 | 93 | if in_pem_part: 94 | raise ValueError('No PEM end marker "%s" found' % pem_end) 95 | 96 | # Base64-decode the contents 97 | pem = b('').join(pem_lines) 98 | return base64.standard_b64decode(pem) 99 | 100 | 101 | def save_pem(contents, pem_marker): 102 | """Saves a PEM file. 103 | 104 | :param contents: the contents to encode in PEM format 105 | :param pem_marker: the marker of the PEM content, such as 'RSA PRIVATE KEY' 106 | when your file has '-----BEGIN RSA PRIVATE KEY-----' and 107 | '-----END RSA PRIVATE KEY-----' markers. 108 | 109 | :return: the base64-encoded content between the start and end markers. 110 | 111 | """ 112 | 113 | (pem_start, pem_end) = _markers(pem_marker) 114 | 115 | b64 = base64.standard_b64encode(contents).replace(b('\n'), b('')) 116 | pem_lines = [pem_start] 117 | 118 | for block_start in range(0, len(b64), 64): 119 | block = b64[block_start:block_start + 64] 120 | pem_lines.append(block) 121 | 122 | pem_lines.append(pem_end) 123 | pem_lines.append(b('')) 124 | 125 | return b('\n').join(pem_lines) 126 | -------------------------------------------------------------------------------- /requests/packages/chardet/charsetgroupprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Communicator client code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from . import constants 29 | import sys 30 | from .charsetprober import CharSetProber 31 | 32 | 33 | class CharSetGroupProber(CharSetProber): 34 | def __init__(self): 35 | CharSetProber.__init__(self) 36 | self._mActiveNum = 0 37 | self._mProbers = [] 38 | self._mBestGuessProber = None 39 | 40 | def reset(self): 41 | CharSetProber.reset(self) 42 | self._mActiveNum = 0 43 | for prober in self._mProbers: 44 | if prober: 45 | prober.reset() 46 | prober.active = True 47 | self._mActiveNum += 1 48 | self._mBestGuessProber = None 49 | 50 | def get_charset_name(self): 51 | if not self._mBestGuessProber: 52 | self.get_confidence() 53 | if not self._mBestGuessProber: 54 | return None 55 | # self._mBestGuessProber = self._mProbers[0] 56 | return self._mBestGuessProber.get_charset_name() 57 | 58 | def feed(self, aBuf): 59 | for prober in self._mProbers: 60 | if not prober: 61 | continue 62 | if not prober.active: 63 | continue 64 | st = prober.feed(aBuf) 65 | if not st: 66 | continue 67 | if st == constants.eFoundIt: 68 | self._mBestGuessProber = prober 69 | return self.get_state() 70 | elif st == constants.eNotMe: 71 | prober.active = False 72 | self._mActiveNum -= 1 73 | if self._mActiveNum <= 0: 74 | self._mState = constants.eNotMe 75 | return self.get_state() 76 | return self.get_state() 77 | 78 | def get_confidence(self): 79 | st = self.get_state() 80 | if st == constants.eFoundIt: 81 | return 0.99 82 | elif st == constants.eNotMe: 83 | return 0.01 84 | bestConf = 0.0 85 | self._mBestGuessProber = None 86 | for prober in self._mProbers: 87 | if not prober: 88 | continue 89 | if not prober.active: 90 | if constants._debug: 91 | sys.stderr.write(prober.get_charset_name() 92 | + ' not active\n') 93 | continue 94 | cf = prober.get_confidence() 95 | if constants._debug: 96 | sys.stderr.write('%s confidence = %s\n' % 97 | (prober.get_charset_name(), cf)) 98 | if bestConf < cf: 99 | bestConf = cf 100 | self._mBestGuessProber = prober 101 | if not self._mBestGuessProber: 102 | return 0.0 103 | return bestConf 104 | # else: 105 | # self._mBestGuessProber = self._mProbers[0] 106 | # return self._mBestGuessProber.get_confidence() 107 | -------------------------------------------------------------------------------- /requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py: -------------------------------------------------------------------------------- 1 | """The match_hostname() function from Python 3.3.3, essential when using SSL.""" 2 | 3 | # Note: This file is under the PSF license as the code comes from the python 4 | # stdlib. http://docs.python.org/3/license.html 5 | 6 | import re 7 | 8 | __version__ = '3.4.0.2' 9 | 10 | class CertificateError(ValueError): 11 | pass 12 | 13 | 14 | def _dnsname_match(dn, hostname, max_wildcards=1): 15 | """Matching according to RFC 6125, section 6.4.3 16 | 17 | http://tools.ietf.org/html/rfc6125#section-6.4.3 18 | """ 19 | pats = [] 20 | if not dn: 21 | return False 22 | 23 | # Ported from python3-syntax: 24 | # leftmost, *remainder = dn.split(r'.') 25 | parts = dn.split(r'.') 26 | leftmost = parts[0] 27 | remainder = parts[1:] 28 | 29 | wildcards = leftmost.count('*') 30 | if wildcards > max_wildcards: 31 | # Issue #17980: avoid denials of service by refusing more 32 | # than one wildcard per fragment. A survey of established 33 | # policy among SSL implementations showed it to be a 34 | # reasonable choice. 35 | raise CertificateError( 36 | "too many wildcards in certificate DNS name: " + repr(dn)) 37 | 38 | # speed up common case w/o wildcards 39 | if not wildcards: 40 | return dn.lower() == hostname.lower() 41 | 42 | # RFC 6125, section 6.4.3, subitem 1. 43 | # The client SHOULD NOT attempt to match a presented identifier in which 44 | # the wildcard character comprises a label other than the left-most label. 45 | if leftmost == '*': 46 | # When '*' is a fragment by itself, it matches a non-empty dotless 47 | # fragment. 48 | pats.append('[^.]+') 49 | elif leftmost.startswith('xn--') or hostname.startswith('xn--'): 50 | # RFC 6125, section 6.4.3, subitem 3. 51 | # The client SHOULD NOT attempt to match a presented identifier 52 | # where the wildcard character is embedded within an A-label or 53 | # U-label of an internationalized domain name. 54 | pats.append(re.escape(leftmost)) 55 | else: 56 | # Otherwise, '*' matches any dotless string, e.g. www* 57 | pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) 58 | 59 | # add the remaining fragments, ignore any wildcards 60 | for frag in remainder: 61 | pats.append(re.escape(frag)) 62 | 63 | pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) 64 | return pat.match(hostname) 65 | 66 | 67 | def match_hostname(cert, hostname): 68 | """Verify that *cert* (in decoded format as returned by 69 | SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 70 | rules are followed, but IP addresses are not accepted for *hostname*. 71 | 72 | CertificateError is raised on failure. On success, the function 73 | returns nothing. 74 | """ 75 | if not cert: 76 | raise ValueError("empty or no certificate") 77 | dnsnames = [] 78 | san = cert.get('subjectAltName', ()) 79 | for key, value in san: 80 | if key == 'DNS': 81 | if _dnsname_match(value, hostname): 82 | return 83 | dnsnames.append(value) 84 | if not dnsnames: 85 | # The subject is only checked when there is no dNSName entry 86 | # in subjectAltName 87 | for sub in cert.get('subject', ()): 88 | for key, value in sub: 89 | # XXX according to RFC 2818, the most specific Common Name 90 | # must be used. 91 | if key == 'commonName': 92 | if _dnsname_match(value, hostname): 93 | return 94 | dnsnames.append(value) 95 | if len(dnsnames) > 1: 96 | raise CertificateError("hostname %r " 97 | "doesn't match either of %s" 98 | % (hostname, ', '.join(map(repr, dnsnames)))) 99 | elif len(dnsnames) == 1: 100 | raise CertificateError("hostname %r " 101 | "doesn't match %r" 102 | % (hostname, dnsnames[0])) 103 | else: 104 | raise CertificateError("no appropriate commonName or " 105 | "subjectAltName fields were found") 106 | -------------------------------------------------------------------------------- /rsa/_compat.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Sybren A. Stüvel 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Python compatibility wrappers.""" 18 | 19 | from __future__ import absolute_import 20 | 21 | import sys 22 | from struct import pack 23 | 24 | try: 25 | MAX_INT = sys.maxsize 26 | except AttributeError: 27 | MAX_INT = sys.maxint 28 | 29 | MAX_INT64 = (1 << 63) - 1 30 | MAX_INT32 = (1 << 31) - 1 31 | MAX_INT16 = (1 << 15) - 1 32 | 33 | # Determine the word size of the processor. 34 | if MAX_INT == MAX_INT64: 35 | # 64-bit processor. 36 | MACHINE_WORD_SIZE = 64 37 | elif MAX_INT == MAX_INT32: 38 | # 32-bit processor. 39 | MACHINE_WORD_SIZE = 32 40 | else: 41 | # Else we just assume 64-bit processor keeping up with modern times. 42 | MACHINE_WORD_SIZE = 64 43 | 44 | try: 45 | # < Python3 46 | unicode_type = unicode 47 | except NameError: 48 | # Python3. 49 | unicode_type = str 50 | 51 | # Fake byte literals. 52 | if str is unicode_type: 53 | def byte_literal(s): 54 | return s.encode('latin1') 55 | else: 56 | def byte_literal(s): 57 | return s 58 | 59 | # ``long`` is no more. Do type detection using this instead. 60 | try: 61 | integer_types = (int, long) 62 | except NameError: 63 | integer_types = (int,) 64 | 65 | b = byte_literal 66 | 67 | # To avoid calling b() multiple times in tight loops. 68 | ZERO_BYTE = b('\x00') 69 | EMPTY_BYTE = b('') 70 | 71 | 72 | def is_bytes(obj): 73 | """ 74 | Determines whether the given value is a byte string. 75 | 76 | :param obj: 77 | The value to test. 78 | :returns: 79 | ``True`` if ``value`` is a byte string; ``False`` otherwise. 80 | """ 81 | return isinstance(obj, bytes) 82 | 83 | 84 | def is_integer(obj): 85 | """ 86 | Determines whether the given value is an integer. 87 | 88 | :param obj: 89 | The value to test. 90 | :returns: 91 | ``True`` if ``value`` is an integer; ``False`` otherwise. 92 | """ 93 | return isinstance(obj, integer_types) 94 | 95 | 96 | def byte(num): 97 | """ 98 | Converts a number between 0 and 255 (both inclusive) to a base-256 (byte) 99 | representation. 100 | 101 | Use it as a replacement for ``chr`` where you are expecting a byte 102 | because this will work on all current versions of Python:: 103 | 104 | :param num: 105 | An unsigned integer between 0 and 255 (both inclusive). 106 | :returns: 107 | A single byte. 108 | """ 109 | return pack("B", num) 110 | 111 | 112 | def get_word_alignment(num, force_arch=64, 113 | _machine_word_size=MACHINE_WORD_SIZE): 114 | """ 115 | Returns alignment details for the given number based on the platform 116 | Python is running on. 117 | 118 | :param num: 119 | Unsigned integral number. 120 | :param force_arch: 121 | If you don't want to use 64-bit unsigned chunks, set this to 122 | anything other than 64. 32-bit chunks will be preferred then. 123 | Default 64 will be used when on a 64-bit machine. 124 | :param _machine_word_size: 125 | (Internal) The machine word size used for alignment. 126 | :returns: 127 | 4-tuple:: 128 | 129 | (word_bits, word_bytes, 130 | max_uint, packing_format_type) 131 | """ 132 | max_uint64 = 0xffffffffffffffff 133 | max_uint32 = 0xffffffff 134 | max_uint16 = 0xffff 135 | max_uint8 = 0xff 136 | 137 | if force_arch == 64 and _machine_word_size >= 64 and num > max_uint32: 138 | # 64-bit unsigned integer. 139 | return 64, 8, max_uint64, "Q" 140 | elif num > max_uint16: 141 | # 32-bit unsigned integer 142 | return 32, 4, max_uint32, "L" 143 | elif num > max_uint8: 144 | # 16-bit unsigned integer. 145 | return 16, 2, max_uint16, "H" 146 | else: 147 | # 8-bit unsigned integer. 148 | return 8, 1, max_uint8, "B" 149 | -------------------------------------------------------------------------------- /info_for_v2.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bundleid 6 | com.cielpy.uploadimagestoweibo 7 | category 8 | Tools 9 | connections 10 | 11 | CB907A05-64AE-433B-95C4-C3300711261A 12 | 13 | 14 | destinationuid 15 | D0400CC7-88CB-4E98-B3E9-64B804C850FB 16 | modifiers 17 | 0 18 | modifiersubtext 19 | 20 | 21 | 22 | EAD47B56-155B-473E-9182-3869C939D153 23 | 24 | 25 | destinationuid 26 | D2F64BCC-86C2-42B5-B965-89B6D6C5A627 27 | modifiers 28 | 0 29 | modifiersubtext 30 | 31 | 32 | 33 | 34 | createdby 35 | cielpy 36 | description 37 | 上传剪切板图片到微博,并复制地址到剪切板 38 | disabled 39 | 40 | name 41 | UploadImagesToWeibo 42 | objects 43 | 44 | 45 | config 46 | 47 | action 48 | 0 49 | argument 50 | 0 51 | hotkey 52 | 0 53 | hotmod 54 | 0 55 | hotstring 56 | 57 | leftcursor 58 | 59 | modsmode 60 | 0 61 | relatedAppsMode 62 | 0 63 | 64 | type 65 | alfred.workflow.trigger.hotkey 66 | uid 67 | CB907A05-64AE-433B-95C4-C3300711261A 68 | version 69 | 1 70 | 71 | 72 | config 73 | 74 | concurrently 75 | 76 | escaping 77 | 102 78 | script 79 | python get_image_url.py 80 | type 81 | 0 82 | 83 | type 84 | alfred.workflow.action.script 85 | uid 86 | D0400CC7-88CB-4E98-B3E9-64B804C850FB 87 | version 88 | 0 89 | 90 | 91 | config 92 | 93 | action 94 | 0 95 | argument 96 | 0 97 | hotkey 98 | 0 99 | hotmod 100 | 0 101 | hotstring 102 | 103 | leftcursor 104 | 105 | modsmode 106 | 0 107 | relatedAppsMode 108 | 0 109 | 110 | type 111 | alfred.workflow.trigger.hotkey 112 | uid 113 | EAD47B56-155B-473E-9182-3869C939D153 114 | version 115 | 1 116 | 117 | 118 | config 119 | 120 | concurrently 121 | 122 | escaping 123 | 102 124 | script 125 | python get_markdown.py 126 | type 127 | 0 128 | 129 | type 130 | alfred.workflow.action.script 131 | uid 132 | D2F64BCC-86C2-42B5-B965-89B6D6C5A627 133 | version 134 | 0 135 | 136 | 137 | readme 138 | 139 | uidata 140 | 141 | CB907A05-64AE-433B-95C4-C3300711261A 142 | 143 | ypos 144 | 60 145 | 146 | D0400CC7-88CB-4E98-B3E9-64B804C850FB 147 | 148 | ypos 149 | 60 150 | 151 | D2F64BCC-86C2-42B5-B965-89B6D6C5A627 152 | 153 | ypos 154 | 260 155 | 156 | EAD47B56-155B-473E-9182-3869C939D153 157 | 158 | ypos 159 | 260 160 | 161 | 162 | webaddress 163 | https://imciel.com/ 164 | 165 | 166 | -------------------------------------------------------------------------------- /requests/packages/urllib3/contrib/ntlmpool.py: -------------------------------------------------------------------------------- 1 | """ 2 | NTLM authenticating pool, contributed by erikcederstran 3 | 4 | Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10 5 | """ 6 | from __future__ import absolute_import 7 | 8 | try: 9 | from http.client import HTTPSConnection 10 | except ImportError: 11 | from httplib import HTTPSConnection 12 | from logging import getLogger 13 | from ntlm import ntlm 14 | 15 | from urllib3 import HTTPSConnectionPool 16 | 17 | 18 | log = getLogger(__name__) 19 | 20 | 21 | class NTLMConnectionPool(HTTPSConnectionPool): 22 | """ 23 | Implements an NTLM authentication version of an urllib3 connection pool 24 | """ 25 | 26 | scheme = 'https' 27 | 28 | def __init__(self, user, pw, authurl, *args, **kwargs): 29 | """ 30 | authurl is a random URL on the server that is protected by NTLM. 31 | user is the Windows user, probably in the DOMAIN\\username format. 32 | pw is the password for the user. 33 | """ 34 | super(NTLMConnectionPool, self).__init__(*args, **kwargs) 35 | self.authurl = authurl 36 | self.rawuser = user 37 | user_parts = user.split('\\', 1) 38 | self.domain = user_parts[0].upper() 39 | self.user = user_parts[1] 40 | self.pw = pw 41 | 42 | def _new_conn(self): 43 | # Performs the NTLM handshake that secures the connection. The socket 44 | # must be kept open while requests are performed. 45 | self.num_connections += 1 46 | log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s' % 47 | (self.num_connections, self.host, self.authurl)) 48 | 49 | headers = {} 50 | headers['Connection'] = 'Keep-Alive' 51 | req_header = 'Authorization' 52 | resp_header = 'www-authenticate' 53 | 54 | conn = HTTPSConnection(host=self.host, port=self.port) 55 | 56 | # Send negotiation message 57 | headers[req_header] = ( 58 | 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.rawuser)) 59 | log.debug('Request headers: %s' % headers) 60 | conn.request('GET', self.authurl, None, headers) 61 | res = conn.getresponse() 62 | reshdr = dict(res.getheaders()) 63 | log.debug('Response status: %s %s' % (res.status, res.reason)) 64 | log.debug('Response headers: %s' % reshdr) 65 | log.debug('Response data: %s [...]' % res.read(100)) 66 | 67 | # Remove the reference to the socket, so that it can not be closed by 68 | # the response object (we want to keep the socket open) 69 | res.fp = None 70 | 71 | # Server should respond with a challenge message 72 | auth_header_values = reshdr[resp_header].split(', ') 73 | auth_header_value = None 74 | for s in auth_header_values: 75 | if s[:5] == 'NTLM ': 76 | auth_header_value = s[5:] 77 | if auth_header_value is None: 78 | raise Exception('Unexpected %s response header: %s' % 79 | (resp_header, reshdr[resp_header])) 80 | 81 | # Send authentication message 82 | ServerChallenge, NegotiateFlags = \ 83 | ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value) 84 | auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, 85 | self.user, 86 | self.domain, 87 | self.pw, 88 | NegotiateFlags) 89 | headers[req_header] = 'NTLM %s' % auth_msg 90 | log.debug('Request headers: %s' % headers) 91 | conn.request('GET', self.authurl, None, headers) 92 | res = conn.getresponse() 93 | log.debug('Response status: %s %s' % (res.status, res.reason)) 94 | log.debug('Response headers: %s' % dict(res.getheaders())) 95 | log.debug('Response data: %s [...]' % res.read()[:100]) 96 | if res.status != 200: 97 | if res.status == 401: 98 | raise Exception('Server rejected request: wrong ' 99 | 'username or password') 100 | raise Exception('Wrong server response: %s %s' % 101 | (res.status, res.reason)) 102 | 103 | res.fp = None 104 | log.debug('Connection established') 105 | return conn 106 | 107 | def urlopen(self, method, url, body=None, headers=None, retries=3, 108 | redirect=True, assert_same_host=True): 109 | if headers is None: 110 | headers = {} 111 | headers['Connection'] = 'Keep-Alive' 112 | return super(NTLMConnectionPool, self).urlopen(method, url, body, 113 | headers, retries, 114 | redirect, 115 | assert_same_host) 116 | -------------------------------------------------------------------------------- /requests/packages/chardet/sbcharsetprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Universal charset detector code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 2001 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # Shy Shalom - original C code 12 | # 13 | # This library is free software; you can redistribute it and/or 14 | # modify it under the terms of the GNU Lesser General Public 15 | # License as published by the Free Software Foundation; either 16 | # version 2.1 of the License, or (at your option) any later version. 17 | # 18 | # This library is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | # Lesser General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Lesser General Public 24 | # License along with this library; if not, write to the Free Software 25 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 26 | # 02110-1301 USA 27 | ######################### END LICENSE BLOCK ######################### 28 | 29 | import sys 30 | from . import constants 31 | from .charsetprober import CharSetProber 32 | from .compat import wrap_ord 33 | 34 | SAMPLE_SIZE = 64 35 | SB_ENOUGH_REL_THRESHOLD = 1024 36 | POSITIVE_SHORTCUT_THRESHOLD = 0.95 37 | NEGATIVE_SHORTCUT_THRESHOLD = 0.05 38 | SYMBOL_CAT_ORDER = 250 39 | NUMBER_OF_SEQ_CAT = 4 40 | POSITIVE_CAT = NUMBER_OF_SEQ_CAT - 1 41 | #NEGATIVE_CAT = 0 42 | 43 | 44 | class SingleByteCharSetProber(CharSetProber): 45 | def __init__(self, model, reversed=False, nameProber=None): 46 | CharSetProber.__init__(self) 47 | self._mModel = model 48 | # TRUE if we need to reverse every pair in the model lookup 49 | self._mReversed = reversed 50 | # Optional auxiliary prober for name decision 51 | self._mNameProber = nameProber 52 | self.reset() 53 | 54 | def reset(self): 55 | CharSetProber.reset(self) 56 | # char order of last character 57 | self._mLastOrder = 255 58 | self._mSeqCounters = [0] * NUMBER_OF_SEQ_CAT 59 | self._mTotalSeqs = 0 60 | self._mTotalChar = 0 61 | # characters that fall in our sampling range 62 | self._mFreqChar = 0 63 | 64 | def get_charset_name(self): 65 | if self._mNameProber: 66 | return self._mNameProber.get_charset_name() 67 | else: 68 | return self._mModel['charsetName'] 69 | 70 | def feed(self, aBuf): 71 | if not self._mModel['keepEnglishLetter']: 72 | aBuf = self.filter_without_english_letters(aBuf) 73 | aLen = len(aBuf) 74 | if not aLen: 75 | return self.get_state() 76 | for c in aBuf: 77 | order = self._mModel['charToOrderMap'][wrap_ord(c)] 78 | if order < SYMBOL_CAT_ORDER: 79 | self._mTotalChar += 1 80 | if order < SAMPLE_SIZE: 81 | self._mFreqChar += 1 82 | if self._mLastOrder < SAMPLE_SIZE: 83 | self._mTotalSeqs += 1 84 | if not self._mReversed: 85 | i = (self._mLastOrder * SAMPLE_SIZE) + order 86 | model = self._mModel['precedenceMatrix'][i] 87 | else: # reverse the order of the letters in the lookup 88 | i = (order * SAMPLE_SIZE) + self._mLastOrder 89 | model = self._mModel['precedenceMatrix'][i] 90 | self._mSeqCounters[model] += 1 91 | self._mLastOrder = order 92 | 93 | if self.get_state() == constants.eDetecting: 94 | if self._mTotalSeqs > SB_ENOUGH_REL_THRESHOLD: 95 | cf = self.get_confidence() 96 | if cf > POSITIVE_SHORTCUT_THRESHOLD: 97 | if constants._debug: 98 | sys.stderr.write('%s confidence = %s, we have a' 99 | 'winner\n' % 100 | (self._mModel['charsetName'], cf)) 101 | self._mState = constants.eFoundIt 102 | elif cf < NEGATIVE_SHORTCUT_THRESHOLD: 103 | if constants._debug: 104 | sys.stderr.write('%s confidence = %s, below negative' 105 | 'shortcut threshhold %s\n' % 106 | (self._mModel['charsetName'], cf, 107 | NEGATIVE_SHORTCUT_THRESHOLD)) 108 | self._mState = constants.eNotMe 109 | 110 | return self.get_state() 111 | 112 | def get_confidence(self): 113 | r = 0.01 114 | if self._mTotalSeqs > 0: 115 | r = ((1.0 * self._mSeqCounters[POSITIVE_CAT]) / self._mTotalSeqs 116 | / self._mModel['mTypicalPositiveRatio']) 117 | r = r * self._mFreqChar / self._mTotalChar 118 | if r >= 1.0: 119 | r = 0.99 120 | return r 121 | -------------------------------------------------------------------------------- /rsa/prime.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Sybren A. Stüvel 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Numerical functions related to primes. 18 | 19 | Implementation based on the book Algorithm Design by Michael T. Goodrich and 20 | Roberto Tamassia, 2002. 21 | """ 22 | 23 | import rsa.randnum 24 | 25 | __all__ = ['getprime', 'are_relatively_prime'] 26 | 27 | 28 | def gcd(p, q): 29 | """Returns the greatest common divisor of p and q 30 | 31 | >>> gcd(48, 180) 32 | 12 33 | """ 34 | 35 | while q != 0: 36 | (p, q) = (q, p % q) 37 | return p 38 | 39 | 40 | def miller_rabin_primality_testing(n, k): 41 | """Calculates whether n is composite (which is always correct) or prime 42 | (which theoretically is incorrect with error probability 4**-k), by 43 | applying Miller-Rabin primality testing. 44 | 45 | For reference and implementation example, see: 46 | https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test 47 | 48 | :param n: Integer to be tested for primality. 49 | :type n: int 50 | :param k: Number of rounds (witnesses) of Miller-Rabin testing. 51 | :type k: int 52 | :return: False if the number is composite, True if it's probably prime. 53 | :rtype: bool 54 | """ 55 | 56 | # prevent potential infinite loop when d = 0 57 | if n < 2: 58 | return False 59 | 60 | # Decompose (n - 1) to write it as (2 ** r) * d 61 | # While d is even, divide it by 2 and increase the exponent. 62 | d = n - 1 63 | r = 0 64 | 65 | while not (d & 1): 66 | r += 1 67 | d >>= 1 68 | 69 | # Test k witnesses. 70 | for _ in range(k): 71 | # Generate random integer a, where 2 <= a <= (n - 2) 72 | a = rsa.randnum.randint(n - 4) + 2 73 | 74 | x = pow(a, d, n) 75 | if x == 1 or x == n - 1: 76 | continue 77 | 78 | for _ in range(r - 1): 79 | x = pow(x, 2, n) 80 | if x == 1: 81 | # n is composite. 82 | return False 83 | if x == n - 1: 84 | # Exit inner loop and continue with next witness. 85 | break 86 | else: 87 | # If loop doesn't break, n is composite. 88 | return False 89 | 90 | return True 91 | 92 | 93 | def is_prime(number): 94 | """Returns True if the number is prime, and False otherwise. 95 | 96 | >>> is_prime(2) 97 | True 98 | >>> is_prime(42) 99 | False 100 | >>> is_prime(41) 101 | True 102 | >>> [x for x in range(901, 1000) if is_prime(x)] 103 | [907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997] 104 | """ 105 | 106 | # Check for small numbers. 107 | if number < 10: 108 | return number in [2, 3, 5, 7] 109 | 110 | # Check for even numbers. 111 | if not (number & 1): 112 | return False 113 | 114 | # According to NIST FIPS 186-4, Appendix C, Table C.3, minimum number of 115 | # rounds of M-R testing, using an error probability of 2 ** (-100), for 116 | # different p, q bitsizes are: 117 | # * p, q bitsize: 512; rounds: 7 118 | # * p, q bitsize: 1024; rounds: 4 119 | # * p, q bitsize: 1536; rounds: 3 120 | # See: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf 121 | return miller_rabin_primality_testing(number, 7) 122 | 123 | 124 | def getprime(nbits): 125 | """Returns a prime number that can be stored in 'nbits' bits. 126 | 127 | >>> p = getprime(128) 128 | >>> is_prime(p-1) 129 | False 130 | >>> is_prime(p) 131 | True 132 | >>> is_prime(p+1) 133 | False 134 | 135 | >>> from rsa import common 136 | >>> common.bit_size(p) == 128 137 | True 138 | """ 139 | 140 | assert nbits > 3 # the loop wil hang on too small numbers 141 | 142 | while True: 143 | integer = rsa.randnum.read_random_odd_int(nbits) 144 | 145 | # Test for primeness 146 | if is_prime(integer): 147 | return integer 148 | 149 | # Retry if not prime 150 | 151 | 152 | def are_relatively_prime(a, b): 153 | """Returns True if a and b are relatively prime, and False if they 154 | are not. 155 | 156 | >>> are_relatively_prime(2, 3) 157 | True 158 | >>> are_relatively_prime(2, 4) 159 | False 160 | """ 161 | 162 | d = gcd(a, b) 163 | return d == 1 164 | 165 | 166 | if __name__ == '__main__': 167 | print('Running doctests 1000x or until failure') 168 | import doctest 169 | 170 | for count in range(1000): 171 | (failures, tests) = doctest.testmod() 172 | if failures: 173 | break 174 | 175 | if count and count % 100 == 0: 176 | print('%i times' % count) 177 | 178 | print('Doctests done') 179 | -------------------------------------------------------------------------------- /rsa/common.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Sybren A. Stüvel 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Common functionality shared by several modules.""" 18 | 19 | 20 | def bit_size(num): 21 | """ 22 | Number of bits needed to represent a integer excluding any prefix 23 | 0 bits. 24 | 25 | As per definition from https://wiki.python.org/moin/BitManipulation and 26 | to match the behavior of the Python 3 API. 27 | 28 | Usage:: 29 | 30 | >>> bit_size(1023) 31 | 10 32 | >>> bit_size(1024) 33 | 11 34 | >>> bit_size(1025) 35 | 11 36 | 37 | :param num: 38 | Integer value. If num is 0, returns 0. Only the absolute value of the 39 | number is considered. Therefore, signed integers will be abs(num) 40 | before the number's bit length is determined. 41 | :returns: 42 | Returns the number of bits in the integer. 43 | """ 44 | if num == 0: 45 | return 0 46 | if num < 0: 47 | num = -num 48 | 49 | # Make sure this is an int and not a float. 50 | num & 1 51 | 52 | hex_num = "%x" % num 53 | return ((len(hex_num) - 1) * 4) + { 54 | '0': 0, '1': 1, '2': 2, '3': 2, 55 | '4': 3, '5': 3, '6': 3, '7': 3, 56 | '8': 4, '9': 4, 'a': 4, 'b': 4, 57 | 'c': 4, 'd': 4, 'e': 4, 'f': 4, 58 | }[hex_num[0]] 59 | 60 | 61 | def _bit_size(number): 62 | """ 63 | Returns the number of bits required to hold a specific long number. 64 | """ 65 | if number < 0: 66 | raise ValueError('Only nonnegative numbers possible: %s' % number) 67 | 68 | if number == 0: 69 | return 0 70 | 71 | # This works, even with very large numbers. When using math.log(number, 2), 72 | # you'll get rounding errors and it'll fail. 73 | bits = 0 74 | while number: 75 | bits += 1 76 | number >>= 1 77 | 78 | return bits 79 | 80 | 81 | def byte_size(number): 82 | """ 83 | Returns the number of bytes required to hold a specific long number. 84 | 85 | The number of bytes is rounded up. 86 | 87 | Usage:: 88 | 89 | >>> byte_size(1 << 1023) 90 | 128 91 | >>> byte_size((1 << 1024) - 1) 92 | 128 93 | >>> byte_size(1 << 1024) 94 | 129 95 | 96 | :param number: 97 | An unsigned integer 98 | :returns: 99 | The number of bytes required to hold a specific long number. 100 | """ 101 | quanta, mod = divmod(bit_size(number), 8) 102 | if mod or number == 0: 103 | quanta += 1 104 | return quanta 105 | # return int(math.ceil(bit_size(number) / 8.0)) 106 | 107 | 108 | def extended_gcd(a, b): 109 | """Returns a tuple (r, i, j) such that r = gcd(a, b) = ia + jb 110 | """ 111 | # r = gcd(a,b) i = multiplicitive inverse of a mod b 112 | # or j = multiplicitive inverse of b mod a 113 | # Neg return values for i or j are made positive mod b or a respectively 114 | # Iterateive Version is faster and uses much less stack space 115 | x = 0 116 | y = 1 117 | lx = 1 118 | ly = 0 119 | oa = a # Remember original a/b to remove 120 | ob = b # negative values from return results 121 | while b != 0: 122 | q = a // b 123 | (a, b) = (b, a % b) 124 | (x, lx) = ((lx - (q * x)), x) 125 | (y, ly) = ((ly - (q * y)), y) 126 | if lx < 0: 127 | lx += ob # If neg wrap modulo orignal b 128 | if ly < 0: 129 | ly += oa # If neg wrap modulo orignal a 130 | return a, lx, ly # Return only positive values 131 | 132 | 133 | def inverse(x, n): 134 | """Returns x^-1 (mod n) 135 | 136 | >>> inverse(7, 4) 137 | 3 138 | >>> (inverse(143, 4) * 143) % 4 139 | 1 140 | """ 141 | 142 | (divider, inv, _) = extended_gcd(x, n) 143 | 144 | if divider != 1: 145 | raise ValueError("x (%d) and n (%d) are not relatively prime" % (x, n)) 146 | 147 | return inv 148 | 149 | 150 | def crt(a_values, modulo_values): 151 | """Chinese Remainder Theorem. 152 | 153 | Calculates x such that x = a[i] (mod m[i]) for each i. 154 | 155 | :param a_values: the a-values of the above equation 156 | :param modulo_values: the m-values of the above equation 157 | :returns: x such that x = a[i] (mod m[i]) for each i 158 | 159 | 160 | >>> crt([2, 3], [3, 5]) 161 | 8 162 | 163 | >>> crt([2, 3, 2], [3, 5, 7]) 164 | 23 165 | 166 | >>> crt([2, 3, 0], [7, 11, 15]) 167 | 135 168 | """ 169 | 170 | m = 1 171 | x = 0 172 | 173 | for modulo in modulo_values: 174 | m *= modulo 175 | 176 | for (m_i, a_i) in zip(modulo_values, a_values): 177 | M_i = m // m_i 178 | inv = inverse(M_i, m_i) 179 | 180 | x = (x + a_i * M_i * inv) % m 181 | 182 | return x 183 | 184 | 185 | if __name__ == '__main__': 186 | import doctest 187 | 188 | doctest.testmod() 189 | -------------------------------------------------------------------------------- /info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bundleid 6 | com.cielpy.uploadimagestoweibo 7 | category 8 | Tools 9 | connections 10 | 11 | 591565B1-00D5-4E31-857B-B6C8C7EF0CCA 12 | 13 | 14 | destinationuid 15 | 7DA4AAEF-4FE2-45C8-B823-A7364FA44593 16 | modifiers 17 | 0 18 | modifiersubtext 19 | 20 | vitoclose 21 | 22 | 23 | 24 | 6794AEA8-67CE-4356-8100-D1F89FCC6650 25 | 26 | 27 | destinationuid 28 | BD9007C9-F3B0-4C15-9143-AC020D525058 29 | modifiers 30 | 0 31 | modifiersubtext 32 | 33 | vitoclose 34 | 35 | 36 | 37 | 38 | createdby 39 | cielpy 40 | description 41 | 上传剪切板图片到微博,并复制地址到剪切板 42 | disabled 43 | 44 | name 45 | UploadImagesToWeibo 46 | objects 47 | 48 | 49 | config 50 | 51 | action 52 | 0 53 | argument 54 | 0 55 | focusedappvariable 56 | 57 | focusedappvariablename 58 | 59 | hotkey 60 | 9 61 | hotmod 62 | 1310720 63 | hotstring 64 | V 65 | leftcursor 66 | 67 | modsmode 68 | 0 69 | relatedAppsMode 70 | 0 71 | 72 | type 73 | alfred.workflow.trigger.hotkey 74 | uid 75 | 6794AEA8-67CE-4356-8100-D1F89FCC6650 76 | version 77 | 2 78 | 79 | 80 | config 81 | 82 | concurrently 83 | 84 | escaping 85 | 68 86 | script 87 | python get_image_url.py 88 | scriptargtype 89 | 0 90 | scriptfile 91 | 92 | type 93 | 0 94 | 95 | type 96 | alfred.workflow.action.script 97 | uid 98 | BD9007C9-F3B0-4C15-9143-AC020D525058 99 | version 100 | 2 101 | 102 | 103 | config 104 | 105 | action 106 | 0 107 | argument 108 | 0 109 | focusedappvariable 110 | 111 | focusedappvariablename 112 | 113 | hotkey 114 | 11 115 | hotmod 116 | 1310720 117 | hotstring 118 | B 119 | leftcursor 120 | 121 | modsmode 122 | 0 123 | relatedAppsMode 124 | 0 125 | 126 | type 127 | alfred.workflow.trigger.hotkey 128 | uid 129 | 591565B1-00D5-4E31-857B-B6C8C7EF0CCA 130 | version 131 | 2 132 | 133 | 134 | config 135 | 136 | concurrently 137 | 138 | escaping 139 | 102 140 | script 141 | python get_markdown.py 142 | scriptargtype 143 | 1 144 | scriptfile 145 | 146 | type 147 | 0 148 | 149 | type 150 | alfred.workflow.action.script 151 | uid 152 | 7DA4AAEF-4FE2-45C8-B823-A7364FA44593 153 | version 154 | 2 155 | 156 | 157 | readme 158 | 上传剪切板中的图片到新浪微博,并复制 URL 到剪切板。 159 | uidata 160 | 161 | 591565B1-00D5-4E31-857B-B6C8C7EF0CCA 162 | 163 | xpos 164 | 160 165 | ypos 166 | 270 167 | 168 | 6794AEA8-67CE-4356-8100-D1F89FCC6650 169 | 170 | xpos 171 | 160 172 | ypos 173 | 140 174 | 175 | 7DA4AAEF-4FE2-45C8-B823-A7364FA44593 176 | 177 | xpos 178 | 560 179 | ypos 180 | 270 181 | 182 | BD9007C9-F3B0-4C15-9143-AC020D525058 183 | 184 | xpos 185 | 560 186 | ypos 187 | 140 188 | 189 | 190 | version 191 | 0.3.2 192 | webaddress 193 | https://imciel.com/ 194 | 195 | 196 | -------------------------------------------------------------------------------- /rsa/bigfile.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Sybren A. Stüvel 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Large file support 18 | 19 | .. deprecated:: 3.4 20 | 21 | The VARBLOCK format is NOT recommended for general use, has been deprecated since 22 | Python-RSA 3.4, and will be removed in a future release. It's vulnerable to a 23 | number of attacks: 24 | 25 | 1. decrypt/encrypt_bigfile() does not implement `Authenticated encryption`_ nor 26 | uses MACs to verify messages before decrypting public key encrypted messages. 27 | 28 | 2. decrypt/encrypt_bigfile() does not use hybrid encryption (it uses plain RSA) 29 | and has no method for chaining, so block reordering is possible. 30 | 31 | See `issue #19 on Github`_ for more information. 32 | 33 | .. _Authenticated encryption: https://en.wikipedia.org/wiki/Authenticated_encryption 34 | .. _issue #19 on Github: https://github.com/sybrenstuvel/python-rsa/issues/13 35 | 36 | 37 | This module contains functions to: 38 | 39 | - break a file into smaller blocks, and encrypt them, and store the 40 | encrypted blocks in another file. 41 | 42 | - take such an encrypted files, decrypt its blocks, and reconstruct the 43 | original file. 44 | 45 | The encrypted file format is as follows, where || denotes byte concatenation: 46 | 47 | FILE := VERSION || BLOCK || BLOCK ... 48 | 49 | BLOCK := LENGTH || DATA 50 | 51 | LENGTH := varint-encoded length of the subsequent data. Varint comes from 52 | Google Protobuf, and encodes an integer into a variable number of bytes. 53 | Each byte uses the 7 lowest bits to encode the value. The highest bit set 54 | to 1 indicates the next byte is also part of the varint. The last byte will 55 | have this bit set to 0. 56 | 57 | This file format is called the VARBLOCK format, in line with the varint format 58 | used to denote the block sizes. 59 | 60 | """ 61 | 62 | import warnings 63 | 64 | from rsa import key, common, pkcs1, varblock 65 | from rsa._compat import byte 66 | 67 | 68 | def encrypt_bigfile(infile, outfile, pub_key): 69 | """Encrypts a file, writing it to 'outfile' in VARBLOCK format. 70 | 71 | .. deprecated:: 3.4 72 | This function was deprecated in Python-RSA version 3.4 due to security issues 73 | in the VARBLOCK format. See the documentation_ for more information. 74 | 75 | .. _documentation: https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-files 76 | 77 | :param infile: file-like object to read the cleartext from 78 | :param outfile: file-like object to write the crypto in VARBLOCK format to 79 | :param pub_key: :py:class:`rsa.PublicKey` to encrypt with 80 | 81 | """ 82 | 83 | warnings.warn("The 'rsa.bigfile.encrypt_bigfile' function was deprecated in Python-RSA version " 84 | "3.4 due to security issues in the VARBLOCK format. See " 85 | "https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-files " 86 | "for more information.", 87 | DeprecationWarning, stacklevel=2) 88 | 89 | if not isinstance(pub_key, key.PublicKey): 90 | raise TypeError('Public key required, but got %r' % pub_key) 91 | 92 | key_bytes = common.bit_size(pub_key.n) // 8 93 | blocksize = key_bytes - 11 # keep space for PKCS#1 padding 94 | 95 | # Write the version number to the VARBLOCK file 96 | outfile.write(byte(varblock.VARBLOCK_VERSION)) 97 | 98 | # Encrypt and write each block 99 | for block in varblock.yield_fixedblocks(infile, blocksize): 100 | crypto = pkcs1.encrypt(block, pub_key) 101 | 102 | varblock.write_varint(outfile, len(crypto)) 103 | outfile.write(crypto) 104 | 105 | 106 | def decrypt_bigfile(infile, outfile, priv_key): 107 | """Decrypts an encrypted VARBLOCK file, writing it to 'outfile' 108 | 109 | .. deprecated:: 3.4 110 | This function was deprecated in Python-RSA version 3.4 due to security issues 111 | in the VARBLOCK format. See the documentation_ for more information. 112 | 113 | .. _documentation: https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-files 114 | 115 | :param infile: file-like object to read the crypto in VARBLOCK format from 116 | :param outfile: file-like object to write the cleartext to 117 | :param priv_key: :py:class:`rsa.PrivateKey` to decrypt with 118 | 119 | """ 120 | 121 | warnings.warn("The 'rsa.bigfile.decrypt_bigfile' function was deprecated in Python-RSA version " 122 | "3.4 due to security issues in the VARBLOCK format. See " 123 | "https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-files " 124 | "for more information.", 125 | DeprecationWarning, stacklevel=2) 126 | 127 | if not isinstance(priv_key, key.PrivateKey): 128 | raise TypeError('Private key required, but got %r' % priv_key) 129 | 130 | for block in varblock.yield_varblocks(infile): 131 | cleartext = pkcs1.decrypt(block, priv_key) 132 | outfile.write(cleartext) 133 | 134 | 135 | __all__ = ['encrypt_bigfile', 'decrypt_bigfile'] 136 | -------------------------------------------------------------------------------- /requests/packages/chardet/latin1prober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Universal charset detector code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 2001 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # Shy Shalom - original C code 12 | # 13 | # This library is free software; you can redistribute it and/or 14 | # modify it under the terms of the GNU Lesser General Public 15 | # License as published by the Free Software Foundation; either 16 | # version 2.1 of the License, or (at your option) any later version. 17 | # 18 | # This library is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | # Lesser General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Lesser General Public 24 | # License along with this library; if not, write to the Free Software 25 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 26 | # 02110-1301 USA 27 | ######################### END LICENSE BLOCK ######################### 28 | 29 | from .charsetprober import CharSetProber 30 | from .constants import eNotMe 31 | from .compat import wrap_ord 32 | 33 | FREQ_CAT_NUM = 4 34 | 35 | UDF = 0 # undefined 36 | OTH = 1 # other 37 | ASC = 2 # ascii capital letter 38 | ASS = 3 # ascii small letter 39 | ACV = 4 # accent capital vowel 40 | ACO = 5 # accent capital other 41 | ASV = 6 # accent small vowel 42 | ASO = 7 # accent small other 43 | CLASS_NUM = 8 # total classes 44 | 45 | Latin1_CharToClass = ( 46 | OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07 47 | OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F 48 | OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17 49 | OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F 50 | OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27 51 | OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F 52 | OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37 53 | OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F 54 | OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47 55 | ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F 56 | ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57 57 | ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F 58 | OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67 59 | ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F 60 | ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77 61 | ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F 62 | OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87 63 | OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F 64 | UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97 65 | OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F 66 | OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7 67 | OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF 68 | OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7 69 | OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF 70 | ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7 71 | ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF 72 | ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7 73 | ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF 74 | ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7 75 | ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF 76 | ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7 77 | ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF 78 | ) 79 | 80 | # 0 : illegal 81 | # 1 : very unlikely 82 | # 2 : normal 83 | # 3 : very likely 84 | Latin1ClassModel = ( 85 | # UDF OTH ASC ASS ACV ACO ASV ASO 86 | 0, 0, 0, 0, 0, 0, 0, 0, # UDF 87 | 0, 3, 3, 3, 3, 3, 3, 3, # OTH 88 | 0, 3, 3, 3, 3, 3, 3, 3, # ASC 89 | 0, 3, 3, 3, 1, 1, 3, 3, # ASS 90 | 0, 3, 3, 3, 1, 2, 1, 2, # ACV 91 | 0, 3, 3, 3, 3, 3, 3, 3, # ACO 92 | 0, 3, 1, 3, 1, 1, 1, 3, # ASV 93 | 0, 3, 1, 3, 1, 1, 3, 3, # ASO 94 | ) 95 | 96 | 97 | class Latin1Prober(CharSetProber): 98 | def __init__(self): 99 | CharSetProber.__init__(self) 100 | self.reset() 101 | 102 | def reset(self): 103 | self._mLastCharClass = OTH 104 | self._mFreqCounter = [0] * FREQ_CAT_NUM 105 | CharSetProber.reset(self) 106 | 107 | def get_charset_name(self): 108 | return "windows-1252" 109 | 110 | def feed(self, aBuf): 111 | aBuf = self.filter_with_english_letters(aBuf) 112 | for c in aBuf: 113 | charClass = Latin1_CharToClass[wrap_ord(c)] 114 | freq = Latin1ClassModel[(self._mLastCharClass * CLASS_NUM) 115 | + charClass] 116 | if freq == 0: 117 | self._mState = eNotMe 118 | break 119 | self._mFreqCounter[freq] += 1 120 | self._mLastCharClass = charClass 121 | 122 | return self.get_state() 123 | 124 | def get_confidence(self): 125 | if self.get_state() == eNotMe: 126 | return 0.01 127 | 128 | total = sum(self._mFreqCounter) 129 | if total < 0.01: 130 | confidence = 0.0 131 | else: 132 | confidence = ((self._mFreqCounter[3] - self._mFreqCounter[1] * 20.0) 133 | / total) 134 | if confidence < 0.0: 135 | confidence = 0.0 136 | # lower the confidence of latin1 so that other more accurate 137 | # detector can take priority. 138 | confidence = confidence * 0.73 139 | return confidence 140 | -------------------------------------------------------------------------------- /weibo/weibo.py: -------------------------------------------------------------------------------- 1 | # encoding:utf8 2 | 3 | import re 4 | import os 5 | import json 6 | import requests 7 | import cookielib 8 | import rsa 9 | import urllib 10 | import urllib2 11 | import binascii 12 | import base64 13 | from optparse import OptionParser 14 | 15 | cookie_file = 'cookie.txt' 16 | 17 | # ========================函数区开始======================== 18 | # ====================预登陆==================== 19 | 20 | def pre_login(): 21 | pre_login_url = 'http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=MTUyNTUxMjY3OTY%3D&rsakt=mod&checkpin=1&client=ssologin.js%28v1.4.18%29&_=1458836718537' 22 | pre_response = requests.get(pre_login_url).text 23 | pre_content_regex = r'\((.*?)\)' 24 | patten = re.search(pre_content_regex, pre_response) 25 | nonce = None 26 | pubkey = None 27 | servertime = None 28 | rsakv = None 29 | if patten.groups(): 30 | pre_content = patten.group(1) 31 | pre_result = json.loads(pre_content) 32 | nonce = pre_result.get("nonce") 33 | pubkey = pre_result.get('pubkey') 34 | servertime = pre_result.get('servertime') 35 | rsakv = pre_result.get("rsakv") 36 | return nonce, pubkey, servertime, rsakv 37 | 38 | # ====================生成提交表单==================== 39 | def generate_form_data(nonce, pubkey, servertime, rsakv, username, password): 40 | rsa_public_key = int(pubkey, 16) 41 | key = rsa.PublicKey(rsa_public_key, 65537) 42 | message = str(servertime) + '\t' + str(nonce) + '\n' + str(password) 43 | passwd = rsa.encrypt(message, key) 44 | passwd = binascii.b2a_hex(passwd) 45 | username = urllib2.quote(username) 46 | username = base64.encodestring(username) 47 | form_data = { 48 | 'entry': 'weibo', 49 | 'gateway': '1', 50 | 'from': '', 51 | 'savestate': '7', 52 | 'useticket': '1', 53 | 'pagerefer': 'http://weibo.com/p/1005052679342531/home?from=page_100505&mod=TAB&pids=plc_main', 54 | 'vsnf': '1', 55 | 'su': username, 56 | 'service': 'miniblog', 57 | 'servertime': servertime, 58 | 'nonce': nonce, 59 | 'pwencode': 'rsa2', 60 | 'rsakv': rsakv, 61 | 'sp': passwd, 62 | 'sr': '1366*768', 63 | 'encoding': 'UTF-8', 64 | 'prelt': '115', 65 | 'url': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack', 66 | 'returntype': 'META' 67 | } 68 | form_data = urllib.urlencode(form_data) 69 | return form_data 70 | 71 | # ====================登陆并保存cookie==================== 72 | def login(form_data): 73 | url = 'http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)' 74 | headers = ('User-Agent', 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0') 75 | cookie = cookielib.MozillaCookieJar(cookie_file) 76 | handler = urllib2.HTTPCookieProcessor(cookie) 77 | opener = urllib2.build_opener(handler) 78 | opener.addheaders.append(headers) 79 | req = opener.open(url, form_data) 80 | redirect_result = req.read() 81 | login_pattern = r'location.replace\(\'(.*?)\'\)' 82 | login_url = re.search(login_pattern, redirect_result).group(1) 83 | opener.open(login_url).read() 84 | cookie.save(cookie_file, ignore_discard=True, ignore_expires=True) 85 | 86 | 87 | def request_image_url(image_path): 88 | cookie = cookielib.MozillaCookieJar() 89 | cookie.load(cookie_file, ignore_expires=False, ignore_discard=True) 90 | opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie)) 91 | image_url = 'http://picupload.service.weibo.com/interface/pic_upload.php?mime=image%2Fjpeg&data=base64&url=0&markpos=1&logo=&nick=0&marks=1&app=miniblog' 92 | b = base64.b64encode(file(image_path).read()) 93 | data = urllib.urlencode({'b64_data': b}) 94 | result = opener.open(image_url, data).read() 95 | result = re.sub(r"", "", result, flags=re.S) 96 | image_result = json.loads(result) 97 | image_id = image_result.get('data').get('pics').get('pic_1').get('pid') 98 | return 'https://ws3.sinaimg.cn/large/%s.jpg' % image_id 99 | 100 | 101 | def get_image(image_path, username=None, password=None): 102 | url = '' 103 | try: 104 | url = request_image_url(image_path) 105 | except: 106 | try: 107 | if not (username and password): 108 | username = raw_input("输入新浪微博用户名:") 109 | password = raw_input("输入新浪微博密码:") 110 | nonce, pubkey, servertime, rsakv = pre_login() 111 | form_data = generate_form_data(nonce, pubkey, servertime, rsakv, username, password) 112 | login(form_data) 113 | url = request_image_url(image_path) 114 | except Exception, e: 115 | print "登录失败,程序退出" 116 | exit() 117 | return url 118 | 119 | def login_with_username_and_password(username, password): 120 | nonce, pubkey, servertime, rsakv = pre_login() 121 | form_data = generate_form_data(nonce, pubkey, servertime, rsakv, username, password) 122 | login(form_data) 123 | 124 | def check_login_status(): 125 | return os.path.exists(cookie_file) 126 | 127 | if __name__ == '__main__': 128 | usage = "usage: %prog [options] arg" 129 | parser = OptionParser(usage) 130 | parser.add_option("-f", "--file", dest='filepath', help='image file path') 131 | parser.add_option("-u", "--username", dest="username", help="weibo username") 132 | parser.add_option("-p", "--password", dest="password", help="weibo password") 133 | (options, args) = parser.parse_args() 134 | filename = options.filepath 135 | username = options.username 136 | password = options.password 137 | if not filename: 138 | parser.error("Incorrect number of arguments") 139 | print get_image(filename, username, password) 140 | -------------------------------------------------------------------------------- /requests/api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | requests.api 5 | ~~~~~~~~~~~~ 6 | 7 | This module implements the Requests API. 8 | 9 | :copyright: (c) 2012 by Kenneth Reitz. 10 | :license: Apache2, see LICENSE for more details. 11 | 12 | """ 13 | 14 | from . import sessions 15 | 16 | 17 | def request(method, url, **kwargs): 18 | """Constructs and sends a :class:`Request `. 19 | 20 | :param method: method for the new :class:`Request` object. 21 | :param url: URL for the new :class:`Request` object. 22 | :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. 23 | :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. 24 | :param json: (optional) json data to send in the body of the :class:`Request`. 25 | :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. 26 | :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. 27 | :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': ('filename', fileobj)}``) for multipart encoding upload. 28 | :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. 29 | :param timeout: (optional) How long to wait for the server to send data 30 | before giving up, as a float, or a :ref:`(connect timeout, read 31 | timeout) ` tuple. 32 | :type timeout: float or tuple 33 | :param allow_redirects: (optional) Boolean. Set to True if POST/PUT/DELETE redirect following is allowed. 34 | :type allow_redirects: bool 35 | :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. 36 | :param verify: (optional) whether the SSL cert will be verified. A CA_BUNDLE path can also be provided. Defaults to ``True``. 37 | :param stream: (optional) if ``False``, the response content will be immediately downloaded. 38 | :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. 39 | :return: :class:`Response ` object 40 | :rtype: requests.Response 41 | 42 | Usage:: 43 | 44 | >>> import requests 45 | >>> req = requests.request('GET', 'http://httpbin.org/get') 46 | 47 | """ 48 | 49 | # By using the 'with' statement we are sure the session is closed, thus we 50 | # avoid leaving sockets open which can trigger a ResourceWarning in some 51 | # cases, and look like a memory leak in others. 52 | with sessions.Session() as session: 53 | return session.request(method=method, url=url, **kwargs) 54 | 55 | 56 | def get(url, params=None, **kwargs): 57 | """Sends a GET request. 58 | 59 | :param url: URL for the new :class:`Request` object. 60 | :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. 61 | :param \*\*kwargs: Optional arguments that ``request`` takes. 62 | :return: :class:`Response ` object 63 | :rtype: requests.Response 64 | """ 65 | 66 | kwargs.setdefault('allow_redirects', True) 67 | return request('get', url, params=params, **kwargs) 68 | 69 | 70 | def options(url, **kwargs): 71 | """Sends a OPTIONS request. 72 | 73 | :param url: URL for the new :class:`Request` object. 74 | :param \*\*kwargs: Optional arguments that ``request`` takes. 75 | :return: :class:`Response ` object 76 | :rtype: requests.Response 77 | """ 78 | 79 | kwargs.setdefault('allow_redirects', True) 80 | return request('options', url, **kwargs) 81 | 82 | 83 | def head(url, **kwargs): 84 | """Sends a HEAD request. 85 | 86 | :param url: URL for the new :class:`Request` object. 87 | :param \*\*kwargs: Optional arguments that ``request`` takes. 88 | :return: :class:`Response ` object 89 | :rtype: requests.Response 90 | """ 91 | 92 | kwargs.setdefault('allow_redirects', False) 93 | return request('head', url, **kwargs) 94 | 95 | 96 | def post(url, data=None, json=None, **kwargs): 97 | """Sends a POST request. 98 | 99 | :param url: URL for the new :class:`Request` object. 100 | :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. 101 | :param json: (optional) json data to send in the body of the :class:`Request`. 102 | :param \*\*kwargs: Optional arguments that ``request`` takes. 103 | :return: :class:`Response ` object 104 | :rtype: requests.Response 105 | """ 106 | 107 | return request('post', url, data=data, json=json, **kwargs) 108 | 109 | 110 | def put(url, data=None, **kwargs): 111 | """Sends a PUT request. 112 | 113 | :param url: URL for the new :class:`Request` object. 114 | :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. 115 | :param \*\*kwargs: Optional arguments that ``request`` takes. 116 | :return: :class:`Response ` object 117 | :rtype: requests.Response 118 | """ 119 | 120 | return request('put', url, data=data, **kwargs) 121 | 122 | 123 | def patch(url, data=None, **kwargs): 124 | """Sends a PATCH request. 125 | 126 | :param url: URL for the new :class:`Request` object. 127 | :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. 128 | :param \*\*kwargs: Optional arguments that ``request`` takes. 129 | :return: :class:`Response ` object 130 | :rtype: requests.Response 131 | """ 132 | 133 | return request('patch', url, data=data, **kwargs) 134 | 135 | 136 | def delete(url, **kwargs): 137 | """Sends a DELETE request. 138 | 139 | :param url: URL for the new :class:`Request` object. 140 | :param \*\*kwargs: Optional arguments that ``request`` takes. 141 | :return: :class:`Response ` object 142 | :rtype: requests.Response 143 | """ 144 | 145 | return request('delete', url, **kwargs) 146 | -------------------------------------------------------------------------------- /rsa/varblock.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Sybren A. Stüvel 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """VARBLOCK file support 18 | 19 | .. deprecated:: 3.4 20 | 21 | The VARBLOCK format is NOT recommended for general use, has been deprecated since 22 | Python-RSA 3.4, and will be removed in a future release. It's vulnerable to a 23 | number of attacks: 24 | 25 | 1. decrypt/encrypt_bigfile() does not implement `Authenticated encryption`_ nor 26 | uses MACs to verify messages before decrypting public key encrypted messages. 27 | 28 | 2. decrypt/encrypt_bigfile() does not use hybrid encryption (it uses plain RSA) 29 | and has no method for chaining, so block reordering is possible. 30 | 31 | See `issue #19 on Github`_ for more information. 32 | 33 | .. _Authenticated encryption: https://en.wikipedia.org/wiki/Authenticated_encryption 34 | .. _issue #19 on Github: https://github.com/sybrenstuvel/python-rsa/issues/13 35 | 36 | 37 | The VARBLOCK file format is as follows, where || denotes byte concatenation: 38 | 39 | FILE := VERSION || BLOCK || BLOCK ... 40 | 41 | BLOCK := LENGTH || DATA 42 | 43 | LENGTH := varint-encoded length of the subsequent data. Varint comes from 44 | Google Protobuf, and encodes an integer into a variable number of bytes. 45 | Each byte uses the 7 lowest bits to encode the value. The highest bit set 46 | to 1 indicates the next byte is also part of the varint. The last byte will 47 | have this bit set to 0. 48 | 49 | This file format is called the VARBLOCK format, in line with the varint format 50 | used to denote the block sizes. 51 | 52 | """ 53 | 54 | import warnings 55 | 56 | from rsa._compat import byte, b 57 | 58 | ZERO_BYTE = b('\x00') 59 | VARBLOCK_VERSION = 1 60 | 61 | warnings.warn("The 'rsa.varblock' module was deprecated in Python-RSA version " 62 | "3.4 due to security issues in the VARBLOCK format. See " 63 | "https://github.com/sybrenstuvel/python-rsa/issues/13 for more information.", 64 | DeprecationWarning) 65 | 66 | 67 | def read_varint(infile): 68 | """Reads a varint from the file. 69 | 70 | When the first byte to be read indicates EOF, (0, 0) is returned. When an 71 | EOF occurs when at least one byte has been read, an EOFError exception is 72 | raised. 73 | 74 | :param infile: the file-like object to read from. It should have a read() 75 | method. 76 | :returns: (varint, length), the read varint and the number of read bytes. 77 | """ 78 | 79 | varint = 0 80 | read_bytes = 0 81 | 82 | while True: 83 | char = infile.read(1) 84 | if len(char) == 0: 85 | if read_bytes == 0: 86 | return 0, 0 87 | raise EOFError('EOF while reading varint, value is %i so far' % 88 | varint) 89 | 90 | byte = ord(char) 91 | varint += (byte & 0x7F) << (7 * read_bytes) 92 | 93 | read_bytes += 1 94 | 95 | if not byte & 0x80: 96 | return varint, read_bytes 97 | 98 | 99 | def write_varint(outfile, value): 100 | """Writes a varint to a file. 101 | 102 | :param outfile: the file-like object to write to. It should have a write() 103 | method. 104 | :returns: the number of written bytes. 105 | """ 106 | 107 | # there is a big difference between 'write the value 0' (this case) and 108 | # 'there is nothing left to write' (the false-case of the while loop) 109 | 110 | if value == 0: 111 | outfile.write(ZERO_BYTE) 112 | return 1 113 | 114 | written_bytes = 0 115 | while value > 0: 116 | to_write = value & 0x7f 117 | value >>= 7 118 | 119 | if value > 0: 120 | to_write |= 0x80 121 | 122 | outfile.write(byte(to_write)) 123 | written_bytes += 1 124 | 125 | return written_bytes 126 | 127 | 128 | def yield_varblocks(infile): 129 | """Generator, yields each block in the input file. 130 | 131 | :param infile: file to read, is expected to have the VARBLOCK format as 132 | described in the module's docstring. 133 | @yields the contents of each block. 134 | """ 135 | 136 | # Check the version number 137 | first_char = infile.read(1) 138 | if len(first_char) == 0: 139 | raise EOFError('Unable to read VARBLOCK version number') 140 | 141 | version = ord(first_char) 142 | if version != VARBLOCK_VERSION: 143 | raise ValueError('VARBLOCK version %i not supported' % version) 144 | 145 | while True: 146 | (block_size, read_bytes) = read_varint(infile) 147 | 148 | # EOF at block boundary, that's fine. 149 | if read_bytes == 0 and block_size == 0: 150 | break 151 | 152 | block = infile.read(block_size) 153 | 154 | read_size = len(block) 155 | if read_size != block_size: 156 | raise EOFError('Block size is %i, but could read only %i bytes' % 157 | (block_size, read_size)) 158 | 159 | yield block 160 | 161 | 162 | def yield_fixedblocks(infile, blocksize): 163 | """Generator, yields each block of ``blocksize`` bytes in the input file. 164 | 165 | :param infile: file to read and separate in blocks. 166 | :returns: a generator that yields the contents of each block 167 | """ 168 | 169 | while True: 170 | block = infile.read(blocksize) 171 | 172 | read_bytes = len(block) 173 | if read_bytes == 0: 174 | break 175 | 176 | yield block 177 | 178 | if read_bytes < blocksize: 179 | break 180 | -------------------------------------------------------------------------------- /requests/packages/urllib3/exceptions.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | # Base Exceptions 3 | 4 | 5 | class HTTPError(Exception): 6 | "Base exception used by this module." 7 | pass 8 | 9 | 10 | class HTTPWarning(Warning): 11 | "Base warning used by this module." 12 | pass 13 | 14 | 15 | class PoolError(HTTPError): 16 | "Base exception for errors caused within a pool." 17 | def __init__(self, pool, message): 18 | self.pool = pool 19 | HTTPError.__init__(self, "%s: %s" % (pool, message)) 20 | 21 | def __reduce__(self): 22 | # For pickling purposes. 23 | return self.__class__, (None, None) 24 | 25 | 26 | class RequestError(PoolError): 27 | "Base exception for PoolErrors that have associated URLs." 28 | def __init__(self, pool, url, message): 29 | self.url = url 30 | PoolError.__init__(self, pool, message) 31 | 32 | def __reduce__(self): 33 | # For pickling purposes. 34 | return self.__class__, (None, self.url, None) 35 | 36 | 37 | class SSLError(HTTPError): 38 | "Raised when SSL certificate fails in an HTTPS connection." 39 | pass 40 | 41 | 42 | class ProxyError(HTTPError): 43 | "Raised when the connection to a proxy fails." 44 | pass 45 | 46 | 47 | class DecodeError(HTTPError): 48 | "Raised when automatic decoding based on Content-Type fails." 49 | pass 50 | 51 | 52 | class ProtocolError(HTTPError): 53 | "Raised when something unexpected happens mid-request/response." 54 | pass 55 | 56 | 57 | #: Renamed to ProtocolError but aliased for backwards compatibility. 58 | ConnectionError = ProtocolError 59 | 60 | 61 | # Leaf Exceptions 62 | 63 | class MaxRetryError(RequestError): 64 | """Raised when the maximum number of retries is exceeded. 65 | 66 | :param pool: The connection pool 67 | :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool` 68 | :param string url: The requested Url 69 | :param exceptions.Exception reason: The underlying error 70 | 71 | """ 72 | 73 | def __init__(self, pool, url, reason=None): 74 | self.reason = reason 75 | 76 | message = "Max retries exceeded with url: %s (Caused by %r)" % ( 77 | url, reason) 78 | 79 | RequestError.__init__(self, pool, url, message) 80 | 81 | 82 | class HostChangedError(RequestError): 83 | "Raised when an existing pool gets a request for a foreign host." 84 | 85 | def __init__(self, pool, url, retries=3): 86 | message = "Tried to open a foreign host with url: %s" % url 87 | RequestError.__init__(self, pool, url, message) 88 | self.retries = retries 89 | 90 | 91 | class TimeoutStateError(HTTPError): 92 | """ Raised when passing an invalid state to a timeout """ 93 | pass 94 | 95 | 96 | class TimeoutError(HTTPError): 97 | """ Raised when a socket timeout error occurs. 98 | 99 | Catching this error will catch both :exc:`ReadTimeoutErrors 100 | ` and :exc:`ConnectTimeoutErrors `. 101 | """ 102 | pass 103 | 104 | 105 | class ReadTimeoutError(TimeoutError, RequestError): 106 | "Raised when a socket timeout occurs while receiving data from a server" 107 | pass 108 | 109 | 110 | # This timeout error does not have a URL attached and needs to inherit from the 111 | # base HTTPError 112 | class ConnectTimeoutError(TimeoutError): 113 | "Raised when a socket timeout occurs while connecting to a server" 114 | pass 115 | 116 | 117 | class NewConnectionError(ConnectTimeoutError, PoolError): 118 | "Raised when we fail to establish a new connection. Usually ECONNREFUSED." 119 | pass 120 | 121 | 122 | class EmptyPoolError(PoolError): 123 | "Raised when a pool runs out of connections and no more are allowed." 124 | pass 125 | 126 | 127 | class ClosedPoolError(PoolError): 128 | "Raised when a request enters a pool after the pool has been closed." 129 | pass 130 | 131 | 132 | class LocationValueError(ValueError, HTTPError): 133 | "Raised when there is something wrong with a given URL input." 134 | pass 135 | 136 | 137 | class LocationParseError(LocationValueError): 138 | "Raised when get_host or similar fails to parse the URL input." 139 | 140 | def __init__(self, location): 141 | message = "Failed to parse: %s" % location 142 | HTTPError.__init__(self, message) 143 | 144 | self.location = location 145 | 146 | 147 | class ResponseError(HTTPError): 148 | "Used as a container for an error reason supplied in a MaxRetryError." 149 | GENERIC_ERROR = 'too many error responses' 150 | SPECIFIC_ERROR = 'too many {status_code} error responses' 151 | 152 | 153 | class SecurityWarning(HTTPWarning): 154 | "Warned when perfoming security reducing actions" 155 | pass 156 | 157 | 158 | class SubjectAltNameWarning(SecurityWarning): 159 | "Warned when connecting to a host with a certificate missing a SAN." 160 | pass 161 | 162 | 163 | class InsecureRequestWarning(SecurityWarning): 164 | "Warned when making an unverified HTTPS request." 165 | pass 166 | 167 | 168 | class SystemTimeWarning(SecurityWarning): 169 | "Warned when system time is suspected to be wrong" 170 | pass 171 | 172 | 173 | class InsecurePlatformWarning(SecurityWarning): 174 | "Warned when certain SSL configuration is not available on a platform." 175 | pass 176 | 177 | 178 | class SNIMissingWarning(HTTPWarning): 179 | "Warned when making a HTTPS request without SNI available." 180 | pass 181 | 182 | 183 | class ResponseNotChunked(ProtocolError, ValueError): 184 | "Response needs to be chunked in order to read it as chunks." 185 | pass 186 | 187 | 188 | class ProxySchemeUnknown(AssertionError, ValueError): 189 | "ProxyManager does not support the supplied scheme" 190 | # TODO(t-8ch): Stop inheriting from AssertionError in v2.0. 191 | 192 | def __init__(self, scheme): 193 | message = "Not supported proxy scheme %s" % scheme 194 | super(ProxySchemeUnknown, self).__init__(message) 195 | 196 | 197 | class HeaderParsingError(HTTPError): 198 | "Raised by assert_header_parsing, but we convert it to a log.warning statement." 199 | def __init__(self, defects, unparsed_data): 200 | message = '%s, unparsed data: %r' % (defects or 'Unknown', unparsed_data) 201 | super(HeaderParsingError, self).__init__(message) 202 | -------------------------------------------------------------------------------- /requests/packages/urllib3/request.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | try: 3 | from urllib.parse import urlencode 4 | except ImportError: 5 | from urllib import urlencode 6 | 7 | from .filepost import encode_multipart_formdata 8 | 9 | 10 | __all__ = ['RequestMethods'] 11 | 12 | 13 | class RequestMethods(object): 14 | """ 15 | Convenience mixin for classes who implement a :meth:`urlopen` method, such 16 | as :class:`~urllib3.connectionpool.HTTPConnectionPool` and 17 | :class:`~urllib3.poolmanager.PoolManager`. 18 | 19 | Provides behavior for making common types of HTTP request methods and 20 | decides which type of request field encoding to use. 21 | 22 | Specifically, 23 | 24 | :meth:`.request_encode_url` is for sending requests whose fields are 25 | encoded in the URL (such as GET, HEAD, DELETE). 26 | 27 | :meth:`.request_encode_body` is for sending requests whose fields are 28 | encoded in the *body* of the request using multipart or www-form-urlencoded 29 | (such as for POST, PUT, PATCH). 30 | 31 | :meth:`.request` is for making any kind of request, it will look up the 32 | appropriate encoding format and use one of the above two methods to make 33 | the request. 34 | 35 | Initializer parameters: 36 | 37 | :param headers: 38 | Headers to include with all requests, unless other headers are given 39 | explicitly. 40 | """ 41 | 42 | _encode_url_methods = set(['DELETE', 'GET', 'HEAD', 'OPTIONS']) 43 | 44 | def __init__(self, headers=None): 45 | self.headers = headers or {} 46 | 47 | def urlopen(self, method, url, body=None, headers=None, 48 | encode_multipart=True, multipart_boundary=None, 49 | **kw): # Abstract 50 | raise NotImplemented("Classes extending RequestMethods must implement " 51 | "their own ``urlopen`` method.") 52 | 53 | def request(self, method, url, fields=None, headers=None, **urlopen_kw): 54 | """ 55 | Make a request using :meth:`urlopen` with the appropriate encoding of 56 | ``fields`` based on the ``method`` used. 57 | 58 | This is a convenience method that requires the least amount of manual 59 | effort. It can be used in most situations, while still having the 60 | option to drop down to more specific methods when necessary, such as 61 | :meth:`request_encode_url`, :meth:`request_encode_body`, 62 | or even the lowest level :meth:`urlopen`. 63 | """ 64 | method = method.upper() 65 | 66 | if method in self._encode_url_methods: 67 | return self.request_encode_url(method, url, fields=fields, 68 | headers=headers, 69 | **urlopen_kw) 70 | else: 71 | return self.request_encode_body(method, url, fields=fields, 72 | headers=headers, 73 | **urlopen_kw) 74 | 75 | def request_encode_url(self, method, url, fields=None, headers=None, 76 | **urlopen_kw): 77 | """ 78 | Make a request using :meth:`urlopen` with the ``fields`` encoded in 79 | the url. This is useful for request methods like GET, HEAD, DELETE, etc. 80 | """ 81 | if headers is None: 82 | headers = self.headers 83 | 84 | extra_kw = {'headers': headers} 85 | extra_kw.update(urlopen_kw) 86 | 87 | if fields: 88 | url += '?' + urlencode(fields) 89 | 90 | return self.urlopen(method, url, **extra_kw) 91 | 92 | def request_encode_body(self, method, url, fields=None, headers=None, 93 | encode_multipart=True, multipart_boundary=None, 94 | **urlopen_kw): 95 | """ 96 | Make a request using :meth:`urlopen` with the ``fields`` encoded in 97 | the body. This is useful for request methods like POST, PUT, PATCH, etc. 98 | 99 | When ``encode_multipart=True`` (default), then 100 | :meth:`urllib3.filepost.encode_multipart_formdata` is used to encode 101 | the payload with the appropriate content type. Otherwise 102 | :meth:`urllib.urlencode` is used with the 103 | 'application/x-www-form-urlencoded' content type. 104 | 105 | Multipart encoding must be used when posting files, and it's reasonably 106 | safe to use it in other times too. However, it may break request 107 | signing, such as with OAuth. 108 | 109 | Supports an optional ``fields`` parameter of key/value strings AND 110 | key/filetuple. A filetuple is a (filename, data, MIME type) tuple where 111 | the MIME type is optional. For example:: 112 | 113 | fields = { 114 | 'foo': 'bar', 115 | 'fakefile': ('foofile.txt', 'contents of foofile'), 116 | 'realfile': ('barfile.txt', open('realfile').read()), 117 | 'typedfile': ('bazfile.bin', open('bazfile').read(), 118 | 'image/jpeg'), 119 | 'nonamefile': 'contents of nonamefile field', 120 | } 121 | 122 | When uploading a file, providing a filename (the first parameter of the 123 | tuple) is optional but recommended to best mimick behavior of browsers. 124 | 125 | Note that if ``headers`` are supplied, the 'Content-Type' header will 126 | be overwritten because it depends on the dynamic random boundary string 127 | which is used to compose the body of the request. The random boundary 128 | string can be explicitly set with the ``multipart_boundary`` parameter. 129 | """ 130 | if headers is None: 131 | headers = self.headers 132 | 133 | extra_kw = {'headers': {}} 134 | 135 | if fields: 136 | if 'body' in urlopen_kw: 137 | raise TypeError( 138 | "request got values for both 'fields' and 'body', can only specify one.") 139 | 140 | if encode_multipart: 141 | body, content_type = encode_multipart_formdata(fields, boundary=multipart_boundary) 142 | else: 143 | body, content_type = urlencode(fields), 'application/x-www-form-urlencoded' 144 | 145 | extra_kw['body'] = body 146 | extra_kw['headers'] = {'Content-Type': content_type} 147 | 148 | extra_kw['headers'].update(headers) 149 | extra_kw.update(urlopen_kw) 150 | 151 | return self.urlopen(method, url, **extra_kw) 152 | -------------------------------------------------------------------------------- /requests/packages/urllib3/fields.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | import email.utils 3 | import mimetypes 4 | 5 | from .packages import six 6 | 7 | 8 | def guess_content_type(filename, default='application/octet-stream'): 9 | """ 10 | Guess the "Content-Type" of a file. 11 | 12 | :param filename: 13 | The filename to guess the "Content-Type" of using :mod:`mimetypes`. 14 | :param default: 15 | If no "Content-Type" can be guessed, default to `default`. 16 | """ 17 | if filename: 18 | return mimetypes.guess_type(filename)[0] or default 19 | return default 20 | 21 | 22 | def format_header_param(name, value): 23 | """ 24 | Helper function to format and quote a single header parameter. 25 | 26 | Particularly useful for header parameters which might contain 27 | non-ASCII values, like file names. This follows RFC 2231, as 28 | suggested by RFC 2388 Section 4.4. 29 | 30 | :param name: 31 | The name of the parameter, a string expected to be ASCII only. 32 | :param value: 33 | The value of the parameter, provided as a unicode string. 34 | """ 35 | if not any(ch in value for ch in '"\\\r\n'): 36 | result = '%s="%s"' % (name, value) 37 | try: 38 | result.encode('ascii') 39 | except UnicodeEncodeError: 40 | pass 41 | else: 42 | return result 43 | if not six.PY3: # Python 2: 44 | value = value.encode('utf-8') 45 | value = email.utils.encode_rfc2231(value, 'utf-8') 46 | value = '%s*=%s' % (name, value) 47 | return value 48 | 49 | 50 | class RequestField(object): 51 | """ 52 | A data container for request body parameters. 53 | 54 | :param name: 55 | The name of this request field. 56 | :param data: 57 | The data/value body. 58 | :param filename: 59 | An optional filename of the request field. 60 | :param headers: 61 | An optional dict-like object of headers to initially use for the field. 62 | """ 63 | def __init__(self, name, data, filename=None, headers=None): 64 | self._name = name 65 | self._filename = filename 66 | self.data = data 67 | self.headers = {} 68 | if headers: 69 | self.headers = dict(headers) 70 | 71 | @classmethod 72 | def from_tuples(cls, fieldname, value): 73 | """ 74 | A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters. 75 | 76 | Supports constructing :class:`~urllib3.fields.RequestField` from 77 | parameter of key/value strings AND key/filetuple. A filetuple is a 78 | (filename, data, MIME type) tuple where the MIME type is optional. 79 | For example:: 80 | 81 | 'foo': 'bar', 82 | 'fakefile': ('foofile.txt', 'contents of foofile'), 83 | 'realfile': ('barfile.txt', open('realfile').read()), 84 | 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'), 85 | 'nonamefile': 'contents of nonamefile field', 86 | 87 | Field names and filenames must be unicode. 88 | """ 89 | if isinstance(value, tuple): 90 | if len(value) == 3: 91 | filename, data, content_type = value 92 | else: 93 | filename, data = value 94 | content_type = guess_content_type(filename) 95 | else: 96 | filename = None 97 | content_type = None 98 | data = value 99 | 100 | request_param = cls(fieldname, data, filename=filename) 101 | request_param.make_multipart(content_type=content_type) 102 | 103 | return request_param 104 | 105 | def _render_part(self, name, value): 106 | """ 107 | Overridable helper function to format a single header parameter. 108 | 109 | :param name: 110 | The name of the parameter, a string expected to be ASCII only. 111 | :param value: 112 | The value of the parameter, provided as a unicode string. 113 | """ 114 | return format_header_param(name, value) 115 | 116 | def _render_parts(self, header_parts): 117 | """ 118 | Helper function to format and quote a single header. 119 | 120 | Useful for single headers that are composed of multiple items. E.g., 121 | 'Content-Disposition' fields. 122 | 123 | :param header_parts: 124 | A sequence of (k, v) typles or a :class:`dict` of (k, v) to format 125 | as `k1="v1"; k2="v2"; ...`. 126 | """ 127 | parts = [] 128 | iterable = header_parts 129 | if isinstance(header_parts, dict): 130 | iterable = header_parts.items() 131 | 132 | for name, value in iterable: 133 | if value: 134 | parts.append(self._render_part(name, value)) 135 | 136 | return '; '.join(parts) 137 | 138 | def render_headers(self): 139 | """ 140 | Renders the headers for this request field. 141 | """ 142 | lines = [] 143 | 144 | sort_keys = ['Content-Disposition', 'Content-Type', 'Content-Location'] 145 | for sort_key in sort_keys: 146 | if self.headers.get(sort_key, False): 147 | lines.append('%s: %s' % (sort_key, self.headers[sort_key])) 148 | 149 | for header_name, header_value in self.headers.items(): 150 | if header_name not in sort_keys: 151 | if header_value: 152 | lines.append('%s: %s' % (header_name, header_value)) 153 | 154 | lines.append('\r\n') 155 | return '\r\n'.join(lines) 156 | 157 | def make_multipart(self, content_disposition=None, content_type=None, 158 | content_location=None): 159 | """ 160 | Makes this request field into a multipart request field. 161 | 162 | This method overrides "Content-Disposition", "Content-Type" and 163 | "Content-Location" headers to the request parameter. 164 | 165 | :param content_type: 166 | The 'Content-Type' of the request body. 167 | :param content_location: 168 | The 'Content-Location' of the request body. 169 | 170 | """ 171 | self.headers['Content-Disposition'] = content_disposition or 'form-data' 172 | self.headers['Content-Disposition'] += '; '.join([ 173 | '', self._render_parts( 174 | (('name', self._name), ('filename', self._filename)) 175 | ) 176 | ]) 177 | self.headers['Content-Type'] = content_type 178 | self.headers['Content-Location'] = content_location 179 | -------------------------------------------------------------------------------- /requests/packages/urllib3/util/url.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from collections import namedtuple 3 | 4 | from ..exceptions import LocationParseError 5 | 6 | 7 | url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'] 8 | 9 | 10 | class Url(namedtuple('Url', url_attrs)): 11 | """ 12 | Datastructure for representing an HTTP URL. Used as a return value for 13 | :func:`parse_url`. 14 | """ 15 | slots = () 16 | 17 | def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None, 18 | query=None, fragment=None): 19 | if path and not path.startswith('/'): 20 | path = '/' + path 21 | return super(Url, cls).__new__(cls, scheme, auth, host, port, path, 22 | query, fragment) 23 | 24 | @property 25 | def hostname(self): 26 | """For backwards-compatibility with urlparse. We're nice like that.""" 27 | return self.host 28 | 29 | @property 30 | def request_uri(self): 31 | """Absolute path including the query string.""" 32 | uri = self.path or '/' 33 | 34 | if self.query is not None: 35 | uri += '?' + self.query 36 | 37 | return uri 38 | 39 | @property 40 | def netloc(self): 41 | """Network location including host and port""" 42 | if self.port: 43 | return '%s:%d' % (self.host, self.port) 44 | return self.host 45 | 46 | @property 47 | def url(self): 48 | """ 49 | Convert self into a url 50 | 51 | This function should more or less round-trip with :func:`.parse_url`. The 52 | returned url may not be exactly the same as the url inputted to 53 | :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls 54 | with a blank port will have : removed). 55 | 56 | Example: :: 57 | 58 | >>> U = parse_url('http://google.com/mail/') 59 | >>> U.url 60 | 'http://google.com/mail/' 61 | >>> Url('http', 'username:password', 'host.com', 80, 62 | ... '/path', 'query', 'fragment').url 63 | 'http://username:password@host.com:80/path?query#fragment' 64 | """ 65 | scheme, auth, host, port, path, query, fragment = self 66 | url = '' 67 | 68 | # We use "is not None" we want things to happen with empty strings (or 0 port) 69 | if scheme is not None: 70 | url += scheme + '://' 71 | if auth is not None: 72 | url += auth + '@' 73 | if host is not None: 74 | url += host 75 | if port is not None: 76 | url += ':' + str(port) 77 | if path is not None: 78 | url += path 79 | if query is not None: 80 | url += '?' + query 81 | if fragment is not None: 82 | url += '#' + fragment 83 | 84 | return url 85 | 86 | def __str__(self): 87 | return self.url 88 | 89 | 90 | def split_first(s, delims): 91 | """ 92 | Given a string and an iterable of delimiters, split on the first found 93 | delimiter. Return two split parts and the matched delimiter. 94 | 95 | If not found, then the first part is the full input string. 96 | 97 | Example:: 98 | 99 | >>> split_first('foo/bar?baz', '?/=') 100 | ('foo', 'bar?baz', '/') 101 | >>> split_first('foo/bar?baz', '123') 102 | ('foo/bar?baz', '', None) 103 | 104 | Scales linearly with number of delims. Not ideal for large number of delims. 105 | """ 106 | min_idx = None 107 | min_delim = None 108 | for d in delims: 109 | idx = s.find(d) 110 | if idx < 0: 111 | continue 112 | 113 | if min_idx is None or idx < min_idx: 114 | min_idx = idx 115 | min_delim = d 116 | 117 | if min_idx is None or min_idx < 0: 118 | return s, '', None 119 | 120 | return s[:min_idx], s[min_idx + 1:], min_delim 121 | 122 | 123 | def parse_url(url): 124 | """ 125 | Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is 126 | performed to parse incomplete urls. Fields not provided will be None. 127 | 128 | Partly backwards-compatible with :mod:`urlparse`. 129 | 130 | Example:: 131 | 132 | >>> parse_url('http://google.com/mail/') 133 | Url(scheme='http', host='google.com', port=None, path='/mail/', ...) 134 | >>> parse_url('google.com:80') 135 | Url(scheme=None, host='google.com', port=80, path=None, ...) 136 | >>> parse_url('/foo?bar') 137 | Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) 138 | """ 139 | 140 | # While this code has overlap with stdlib's urlparse, it is much 141 | # simplified for our needs and less annoying. 142 | # Additionally, this implementations does silly things to be optimal 143 | # on CPython. 144 | 145 | if not url: 146 | # Empty 147 | return Url() 148 | 149 | scheme = None 150 | auth = None 151 | host = None 152 | port = None 153 | path = None 154 | fragment = None 155 | query = None 156 | 157 | # Scheme 158 | if '://' in url: 159 | scheme, url = url.split('://', 1) 160 | 161 | # Find the earliest Authority Terminator 162 | # (http://tools.ietf.org/html/rfc3986#section-3.2) 163 | url, path_, delim = split_first(url, ['/', '?', '#']) 164 | 165 | if delim: 166 | # Reassemble the path 167 | path = delim + path_ 168 | 169 | # Auth 170 | if '@' in url: 171 | # Last '@' denotes end of auth part 172 | auth, url = url.rsplit('@', 1) 173 | 174 | # IPv6 175 | if url and url[0] == '[': 176 | host, url = url.split(']', 1) 177 | host += ']' 178 | 179 | # Port 180 | if ':' in url: 181 | _host, port = url.split(':', 1) 182 | 183 | if not host: 184 | host = _host 185 | 186 | if port: 187 | # If given, ports must be integers. 188 | if not port.isdigit(): 189 | raise LocationParseError(url) 190 | port = int(port) 191 | else: 192 | # Blank ports are cool, too. (rfc3986#section-3.2.3) 193 | port = None 194 | 195 | elif not host and url: 196 | host = url 197 | 198 | if not path: 199 | return Url(scheme, auth, host, port, path, query, fragment) 200 | 201 | # Fragment 202 | if '#' in path: 203 | path, fragment = path.split('#', 1) 204 | 205 | # Query 206 | if '?' in path: 207 | path, query = path.split('?', 1) 208 | 209 | return Url(scheme, auth, host, port, path, query, fragment) 210 | 211 | 212 | def get_host(url): 213 | """ 214 | Deprecated. Use :func:`.parse_url` instead. 215 | """ 216 | p = parse_url(url) 217 | return p.scheme or 'http', p.hostname, p.port 218 | -------------------------------------------------------------------------------- /requests/packages/chardet/universaldetector.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Universal charset detector code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 2001 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # Shy Shalom - original C code 12 | # 13 | # This library is free software; you can redistribute it and/or 14 | # modify it under the terms of the GNU Lesser General Public 15 | # License as published by the Free Software Foundation; either 16 | # version 2.1 of the License, or (at your option) any later version. 17 | # 18 | # This library is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | # Lesser General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Lesser General Public 24 | # License along with this library; if not, write to the Free Software 25 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 26 | # 02110-1301 USA 27 | ######################### END LICENSE BLOCK ######################### 28 | 29 | from . import constants 30 | import sys 31 | import codecs 32 | from .latin1prober import Latin1Prober # windows-1252 33 | from .mbcsgroupprober import MBCSGroupProber # multi-byte character sets 34 | from .sbcsgroupprober import SBCSGroupProber # single-byte character sets 35 | from .escprober import EscCharSetProber # ISO-2122, etc. 36 | import re 37 | 38 | MINIMUM_THRESHOLD = 0.20 39 | ePureAscii = 0 40 | eEscAscii = 1 41 | eHighbyte = 2 42 | 43 | 44 | class UniversalDetector: 45 | def __init__(self): 46 | self._highBitDetector = re.compile(b'[\x80-\xFF]') 47 | self._escDetector = re.compile(b'(\033|~{)') 48 | self._mEscCharSetProber = None 49 | self._mCharSetProbers = [] 50 | self.reset() 51 | 52 | def reset(self): 53 | self.result = {'encoding': None, 'confidence': 0.0} 54 | self.done = False 55 | self._mStart = True 56 | self._mGotData = False 57 | self._mInputState = ePureAscii 58 | self._mLastChar = b'' 59 | if self._mEscCharSetProber: 60 | self._mEscCharSetProber.reset() 61 | for prober in self._mCharSetProbers: 62 | prober.reset() 63 | 64 | def feed(self, aBuf): 65 | if self.done: 66 | return 67 | 68 | aLen = len(aBuf) 69 | if not aLen: 70 | return 71 | 72 | if not self._mGotData: 73 | # If the data starts with BOM, we know it is UTF 74 | if aBuf[:3] == codecs.BOM_UTF8: 75 | # EF BB BF UTF-8 with BOM 76 | self.result = {'encoding': "UTF-8-SIG", 'confidence': 1.0} 77 | elif aBuf[:4] == codecs.BOM_UTF32_LE: 78 | # FF FE 00 00 UTF-32, little-endian BOM 79 | self.result = {'encoding': "UTF-32LE", 'confidence': 1.0} 80 | elif aBuf[:4] == codecs.BOM_UTF32_BE: 81 | # 00 00 FE FF UTF-32, big-endian BOM 82 | self.result = {'encoding': "UTF-32BE", 'confidence': 1.0} 83 | elif aBuf[:4] == b'\xFE\xFF\x00\x00': 84 | # FE FF 00 00 UCS-4, unusual octet order BOM (3412) 85 | self.result = { 86 | 'encoding': "X-ISO-10646-UCS-4-3412", 87 | 'confidence': 1.0 88 | } 89 | elif aBuf[:4] == b'\x00\x00\xFF\xFE': 90 | # 00 00 FF FE UCS-4, unusual octet order BOM (2143) 91 | self.result = { 92 | 'encoding': "X-ISO-10646-UCS-4-2143", 93 | 'confidence': 1.0 94 | } 95 | elif aBuf[:2] == codecs.BOM_LE: 96 | # FF FE UTF-16, little endian BOM 97 | self.result = {'encoding': "UTF-16LE", 'confidence': 1.0} 98 | elif aBuf[:2] == codecs.BOM_BE: 99 | # FE FF UTF-16, big endian BOM 100 | self.result = {'encoding': "UTF-16BE", 'confidence': 1.0} 101 | 102 | self._mGotData = True 103 | if self.result['encoding'] and (self.result['confidence'] > 0.0): 104 | self.done = True 105 | return 106 | 107 | if self._mInputState == ePureAscii: 108 | if self._highBitDetector.search(aBuf): 109 | self._mInputState = eHighbyte 110 | elif ((self._mInputState == ePureAscii) and 111 | self._escDetector.search(self._mLastChar + aBuf)): 112 | self._mInputState = eEscAscii 113 | 114 | self._mLastChar = aBuf[-1:] 115 | 116 | if self._mInputState == eEscAscii: 117 | if not self._mEscCharSetProber: 118 | self._mEscCharSetProber = EscCharSetProber() 119 | if self._mEscCharSetProber.feed(aBuf) == constants.eFoundIt: 120 | self.result = {'encoding': self._mEscCharSetProber.get_charset_name(), 121 | 'confidence': self._mEscCharSetProber.get_confidence()} 122 | self.done = True 123 | elif self._mInputState == eHighbyte: 124 | if not self._mCharSetProbers: 125 | self._mCharSetProbers = [MBCSGroupProber(), SBCSGroupProber(), 126 | Latin1Prober()] 127 | for prober in self._mCharSetProbers: 128 | if prober.feed(aBuf) == constants.eFoundIt: 129 | self.result = {'encoding': prober.get_charset_name(), 130 | 'confidence': prober.get_confidence()} 131 | self.done = True 132 | break 133 | 134 | def close(self): 135 | if self.done: 136 | return 137 | if not self._mGotData: 138 | if constants._debug: 139 | sys.stderr.write('no data received!\n') 140 | return 141 | self.done = True 142 | 143 | if self._mInputState == ePureAscii: 144 | self.result = {'encoding': 'ascii', 'confidence': 1.0} 145 | return self.result 146 | 147 | if self._mInputState == eHighbyte: 148 | proberConfidence = None 149 | maxProberConfidence = 0.0 150 | maxProber = None 151 | for prober in self._mCharSetProbers: 152 | if not prober: 153 | continue 154 | proberConfidence = prober.get_confidence() 155 | if proberConfidence > maxProberConfidence: 156 | maxProberConfidence = proberConfidence 157 | maxProber = prober 158 | if maxProber and (maxProberConfidence > MINIMUM_THRESHOLD): 159 | self.result = {'encoding': maxProber.get_charset_name(), 160 | 'confidence': maxProber.get_confidence()} 161 | return self.result 162 | 163 | if constants._debug: 164 | sys.stderr.write('no probers hit minimum threshhold\n') 165 | for prober in self._mCharSetProbers[0].mProbers: 166 | if not prober: 167 | continue 168 | sys.stderr.write('%s confidence = %s\n' % 169 | (prober.get_charset_name(), 170 | prober.get_confidence())) 171 | --------------------------------------------------------------------------------