├── .gitignore ├── LICENSE ├── README.md ├── browser_chrome_auto_tool ├── auto_web_tools.py ├── products │ └── TestTest&&&1Test.txt └── splinter │ ├── __init__.py │ ├── browser.py │ ├── cookie_manager.py │ ├── driver │ ├── __init__.py │ ├── djangoclient.py │ ├── element_present.py │ ├── flaskclient.py │ ├── lxmldriver.py │ ├── webdriver │ │ ├── __init__.py │ │ ├── chrome.py │ │ ├── cookie_manager.py │ │ ├── firefox.py │ │ └── remote.py │ └── zopetestbrowser.py │ ├── element_list.py │ ├── exceptions.py │ ├── meta.py │ └── request_handler │ ├── __init__.py │ └── status_code.py ├── decompile_apk ├── APKs │ └── 1 │ │ └── gat5sj99900909b.apk ├── apktool.bat ├── apktool.jar └── decompiling_apk.py ├── game_thirdsdk_check.py └── Game_ThirdSDK_Check.py.py ├── re-sign-ipa ├── .vscode │ ├── launch.json │ └── settings.json ├── MachOView-2.4.9200.dmg ├── embedded.mobileprovision ├── insert_sdks │ ├── .DS_Store │ ├── Frameworks │ │ ├── .DS_Store │ │ ├── MobGiAdsToolModule.framework │ │ │ ├── GCDWebUploader.bundle │ │ │ │ └── Contents │ │ │ │ │ ├── Info.plist │ │ │ │ │ └── Resources │ │ │ │ │ ├── css │ │ │ │ │ ├── bootstrap-theme.css │ │ │ │ │ ├── bootstrap.css │ │ │ │ │ ├── index.css │ │ │ │ │ └── jquery.fileupload.css │ │ │ │ │ ├── en.lproj │ │ │ │ │ └── Localizable.strings │ │ │ │ │ ├── fonts │ │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ │ └── glyphicons-halflings-regular.woff │ │ │ │ │ ├── index.html │ │ │ │ │ └── js │ │ │ │ │ ├── bootstrap.min.js │ │ │ │ │ ├── html5shiv.min.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── jquery.fileupload.js │ │ │ │ │ ├── jquery.iframe-transport.js │ │ │ │ │ ├── jquery.jeditable.js │ │ │ │ │ ├── jquery.min.js │ │ │ │ │ ├── jquery.ui.widget.js │ │ │ │ │ ├── respond.min.js │ │ │ │ │ └── tmpl.min.js │ │ │ ├── Headers │ │ │ │ ├── ADMBProgressHUD.h │ │ │ │ └── MobGiAdsToolModule.h │ │ │ ├── Info.plist │ │ │ ├── MobGiAdsToolModule │ │ │ └── Modules │ │ │ │ └── module.modulemap │ │ └── SDKCommonModule.framework │ │ │ ├── Headers │ │ │ ├── AFAutoPurgingImageCache.h │ │ │ ├── AFHTTPSessionManager.h │ │ │ ├── AFHTTPSessionManagerAdapter.h │ │ │ ├── AFImageDownloader.h │ │ │ ├── AFNetworkActivityIndicatorManager.h │ │ │ ├── AFNetworkReachabilityManager.h │ │ │ ├── AFNetworkReachabilityManagerAdapter.h │ │ │ ├── AFNetworking.h │ │ │ ├── AFSecurityPolicy.h │ │ │ ├── AFURLRequestSerialization.h │ │ │ ├── AFURLResponseSerialization.h │ │ │ ├── AFURLSessionManager.h │ │ │ ├── BasicUtilTools.h │ │ │ ├── JSONAPI.h │ │ │ ├── JSONHTTPClient.h │ │ │ ├── JSONKeyMapper.h │ │ │ ├── JSONModel+networking.h │ │ │ ├── JSONModel.h │ │ │ ├── JSONModelArray.h │ │ │ ├── JSONModelClassProperty.h │ │ │ ├── JSONModelError.h │ │ │ ├── JSONModelLib.h │ │ │ ├── JSONValueTransformer.h │ │ │ ├── NSArray+JSONModel.h │ │ │ ├── Reachability.h │ │ │ ├── SDKCommonModule.h │ │ │ ├── SDKHttpOperationManager.h │ │ │ ├── SDKUtilManager.h │ │ │ ├── UIActivityIndicatorView+AFNetworking.h │ │ │ ├── UIButton+AFNetworking.h │ │ │ ├── UIImage+AFNetworking.h │ │ │ ├── UIImageView+AFNetworking.h │ │ │ ├── UIKit+AFNetworking.h │ │ │ ├── UIProgressView+AFNetworking.h │ │ │ ├── UIRefreshControl+AFNetworking.h │ │ │ └── UIWebView+AFNetworking.h │ │ │ ├── Info.plist │ │ │ ├── Modules │ │ │ └── module.modulemap │ │ │ └── SDKCommonModule │ └── MobGiAdsToolModuleBundle.bundle │ │ ├── error.html │ │ ├── index.html │ │ └── sandbox.html ├── re-sign-ipa.py └── yololib ├── sdk_thinning └── SDK_Thinning.py ├── uploadIPA_checks └── UploadIPA_Checks.py └── xcode_build ├── .vscode ├── launch.json └── settings.json ├── app_main.py ├── auto_generate_app_icons.py ├── auto_generate_macos_app.py ├── gui_main.py ├── pbxproj ├── PBXGenericObject.py ├── PBXKey.py ├── PBXList.py ├── PBXObjects.py ├── PBXRootObject.py ├── XcodeProject.py ├── __init__.py ├── __main__.py ├── pbxcli │ ├── __init__.py │ ├── pbxproj_file.py │ ├── pbxproj_flag.py │ ├── pbxproj_folder.py │ └── pbxproj_show.py ├── pbxextensions │ ├── ProjectFiles.py │ ├── ProjectFlags.py │ ├── ProjectGroups.py │ └── __init__.py └── pbxsections │ ├── PBXAggregateTarget.py │ ├── PBXBuildFile.py │ ├── PBXContainerItemProxy.py │ ├── PBXCopyFilesBuildPhase.py │ ├── PBXFileReference.py │ ├── PBXFrameworksBuildPhase.py │ ├── PBXGenericBuildPhase.py │ ├── PBXGenericTarget.py │ ├── PBXGroup.py │ ├── PBXHeadersBuildPhase.py │ ├── PBXLegacyTarget.py │ ├── PBXNativeTarget.py │ ├── PBXProject.py │ ├── PBXReferenceProxy.py │ ├── PBXResourcesBuildPhase.py │ ├── PBXShellScriptBuildPhase.py │ ├── PBXSourcesBuildPhase.py │ ├── PBXTargetDependency.py │ ├── XCBuildConfiguration.py │ ├── XCConfigurationList.py │ └── __init__.py ├── requirements.txt ├── start_python_venv.py ├── xcode_build.py └── xcode_build_module.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | 7 | # 8 | .DS_Store 9 | *.DS_Store 10 | ./xcode_build/*.DS_Store 11 | ./xcode_build/venv 12 | 13 | # C extensions 14 | *.so 15 | 16 | # Distribution / packaging 17 | .Python 18 | build/ 19 | develop-eggs/ 20 | dist/ 21 | downloads/ 22 | eggs/ 23 | .eggs/ 24 | lib/ 25 | lib64/ 26 | parts/ 27 | sdist/ 28 | var/ 29 | wheels/ 30 | *.egg-info/ 31 | .installed.cfg 32 | *.egg 33 | MANIFEST 34 | 35 | # PyInstaller 36 | # Usually these files are written by a python script from a template 37 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 38 | *.manifest 39 | *.spec 40 | 41 | # Installer logs 42 | pip-log.txt 43 | pip-delete-this-directory.txt 44 | 45 | # Unit test / coverage reports 46 | htmlcov/ 47 | .tox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # pyenv 83 | .python-version 84 | 85 | # celery beat schedule file 86 | celerybeat-schedule 87 | 88 | # SageMath parsed files 89 | *.sage.py 90 | 91 | # Environments 92 | .env 93 | .venv 94 | env/ 95 | venv/ 96 | ENV/ 97 | env.bak/ 98 | venv.bak/ 99 | 100 | # Spyder project settings 101 | .spyderproject 102 | .spyproject 103 | 104 | # Rope project settings 105 | .ropeproject 106 | 107 | # mkdocs documentation 108 | /site 109 | 110 | # mypy 111 | .mypy_cache/ 112 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 12star9 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 使用Python语言开发各种小工具,来提高我们的工作效率! 2 | 3 | #### 目前功能列表: 4 | 5 | - sdk_thinning: 去除iOS静态库(.a或.framework)模拟器架构. 6 | 7 | 工作场景: 在做一些聚合SDK的时候,在提供给游戏接入测试和上线的时候,一般都不需要模拟器架构,而且游戏方在接入SDK的时候也会考虑SDK压缩包的体积问题。 8 | 9 | - game_thirdsdk_check:批量追踪第三方SDK出错检查. 10 | 11 | 工作场景: 游戏接入大量SDK上线后,通过bug监控系统会得到一些报错堆栈信息,涉及SDK数量很多,一个个询问影响沟通效率。 12 | 13 | - decompile_apk:apk反编译. 14 | 15 | 工作场景:一些游戏接入安卓SDK后,在给包给我们相关同事进行集成情况检查的时候,需要同事安装相关环境等操作,太影响效率。 16 | 17 | - browser_chrome_auto_tool:浏览器自动化操作,示例以京东开普勒后台商品操作为演示脚本. 18 | 19 | 工作场景: 之前参与一个项目,运营同事在相关后台进行配置操作,一些操作反复,降低了效率。 20 | 21 | - xcode_build:iOS批量自动打包GUI工具,包含自定义添加SDK功能. 操作演示如下: 22 | 23 | 工作场景: 24 | 25 | 1.之前在给游戏开发商做SDK接入技术支持的时候,很多cp对iOS开发技术并不是很了解,对接SDK和打包都很迷糊,虽然我们根据他们的开发环境输出了不同的插件解 决方案,这一步已经把接入SDK的复杂度基本解决了,但最后依然逃不开打包这一块问题,iOS打包涉及到证书,描述配置文件,包名配置等概念,不难但却很繁琐,如果出个工具把接入SDK和打包问题一并解决,可以大幅度减少沟通。 26 | 27 | 2.游戏在上线之前,都会接入各种SDK,比如登陆,付费,统计,广告等等功能的SDK,不同SDK有不同的接入方式,但接触多了,其实无外乎几种步骤,完全可以把这些步骤机器自动化处理掉。 28 | 29 | 3.有些游戏对接入SDK比较谨慎,比如对接入SDK后,对包体增量大小的影响,如果我们手动在工程里增删SDK来打包计算体积的话,SDK数量一多,就是很花时间的操作了,而且很重复。 30 | 31 | ![image](https://api.stwxsite.com/files?url=screen_gif.gif) 32 | 33 | - re-sign-ipa:iOS包体.ipa(包括.framework)重签名和动态库代码注入. 34 | 35 | 工作场景: 36 | 37 | 1. 了解产品包体情况,比如在对cp的产品进行技术评估的时候,查看本地文件存储机制等。 38 | 2. 未拿到cp产品源码的前提,对集成第三方SDK进行预研。 39 | 40 | - uploadIPA_checks: AppStore审核.ipa包体检查脚本,例如二进制文件__TEXT大小限制检查,目前功能还在完善中. 41 | 42 | 工作场景: 43 | 44 | 游戏打包后,上线前做一些预审核检查,提高提交包体审核效率,减少反复打包情况。 45 | 46 | 47 | 后续不断更新中...... 48 | 49 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/products/TestTest&&&1Test.txt: -------------------------------------------------------------------------------- 1 | Under Armour 安德玛UA女子Tech Graphic短袖T恤 2 | MOCO2018秋季新品翻领字母刺绣条纹衬衫MA183SHT108 摩安珂 3 | GLORIA/歌莉娅冬季新品撞色波浪边修身毛衣17NR5J270 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 splinter authors. All rights reserved. 2 | # Use of this source code is governed by a BSD-style 3 | # license that can be found in the LICENSE file. 4 | 5 | from splinter.browser import Browser # NOQA 6 | 7 | 8 | __version__ = "0.10.0" 9 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/browser.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2012 splinter authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | import sys 8 | 9 | from splinter.driver.webdriver.firefox import WebDriver as FirefoxWebDriver 10 | from splinter.driver.webdriver.remote import WebDriver as RemoteWebDriver 11 | from splinter.driver.webdriver.chrome import WebDriver as ChromeWebDriver 12 | from splinter.exceptions import DriverNotFoundError 13 | 14 | 15 | _DRIVERS = { 16 | "firefox": FirefoxWebDriver, 17 | "remote": RemoteWebDriver, 18 | "chrome": ChromeWebDriver, 19 | } 20 | 21 | if sys.version_info[0] <= 2: 22 | try: 23 | from splinter.driver.zopetestbrowser import ZopeTestBrowser 24 | 25 | _DRIVERS["zope.testbrowser"] = ZopeTestBrowser 26 | except ImportError: 27 | pass 28 | 29 | try: 30 | import django # noqa 31 | from splinter.driver.djangoclient import DjangoClient 32 | 33 | _DRIVERS["django"] = DjangoClient 34 | except ImportError: 35 | pass 36 | 37 | try: 38 | import flask # noqa 39 | from splinter.driver.flaskclient import FlaskClient 40 | 41 | _DRIVERS["flask"] = FlaskClient 42 | except ImportError: 43 | pass 44 | 45 | 46 | def Browser(driver_name="firefox", *args, **kwargs): 47 | """ 48 | Returns a driver instance for the given name. 49 | 50 | When working with ``firefox``, it's possible to provide a profile name 51 | and a list of extensions. 52 | 53 | If you don't provide any driver_name, then ``firefox`` will be used. 54 | 55 | If there is no driver registered with the provided ``driver_name``, this 56 | function will raise a :class:`splinter.exceptions.DriverNotFoundError` 57 | exception. 58 | """ 59 | 60 | try: 61 | driver = _DRIVERS[driver_name] 62 | except KeyError: 63 | raise DriverNotFoundError("No driver for %s" % driver_name) 64 | return driver(*args, **kwargs) 65 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/cookie_manager.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2012 splinter authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | from splinter.meta import InheritedDocs 8 | 9 | 10 | class CookieManagerAPI(InheritedDocs("_CookieManagerAPI", (object,), {})): 11 | """ 12 | An API that specifies how a splinter driver deals with cookies. 13 | 14 | You can add cookies using the :meth:`add ` method, 15 | and remove one or all cookies using 16 | the :meth:`delete ` method. 17 | 18 | A CookieManager acts like a ``dict``, so you can access the value of a 19 | cookie through the [] operator, passing the cookie identifier: 20 | 21 | >>> cookie_manager.add({'name': 'Tony'}) 22 | >>> assert cookie_manager['name'] == 'Tony' 23 | """ 24 | 25 | def add(self, cookies): 26 | """ 27 | Adds a cookie. 28 | 29 | The ``cookie`` parameter is a ``dict`` where each key is an identifier 30 | for the cookie value (like any ``dict``). 31 | 32 | Example of use: 33 | 34 | >>> cookie_manager.add({'name': 'Tony'}) 35 | """ 36 | raise NotImplementedError 37 | 38 | def delete(self, *cookies): 39 | """ 40 | Deletes one or more cookies. You can pass all the cookies identifier 41 | that you want to delete. 42 | 43 | If none identifier is provided, all cookies are deleted. 44 | 45 | Examples: 46 | 47 | >>> cookie_manager.delete() # deletes all cookies 48 | >>> cookie_manager.delete('name', 'birthday', 49 | 'favorite_color') # deletes these three cookies 50 | >>> cookie_manager.delete('name') # deletes one cookie 51 | """ 52 | raise NotImplementedError 53 | 54 | def all(self, verbose=False): 55 | """ 56 | Returns all of the cookies. 57 | 58 | **Note:** If you're using any webdriver and want more info about 59 | the cookie, set the `verbose` parameter to `True` (in other 60 | drivers, it won't make any difference). In this case, this method 61 | will return a list of dicts, each with one cookie's info. 62 | 63 | Examples: 64 | 65 | >>> cookie_manager.add({'name': 'Tony'}) 66 | >>> cookie_manager.all() 67 | [{'name': 'Tony'}] 68 | """ 69 | raise NotImplementedError 70 | 71 | def __getitem__(self, item): 72 | raise NotImplementedError 73 | 74 | def __eq__(self, other_object): 75 | raise NotImplementedError 76 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/driver/djangoclient.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2012 splinter authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | from __future__ import with_statement 8 | import six 9 | from six.moves.urllib import parse 10 | 11 | from splinter.cookie_manager import CookieManagerAPI 12 | from splinter.request_handler.status_code import StatusCode 13 | 14 | from .lxmldriver import LxmlDriver 15 | 16 | 17 | class CookieManager(CookieManagerAPI): 18 | def __init__(self, browser_cookies): 19 | self._cookies = browser_cookies 20 | 21 | def add(self, cookies): 22 | if isinstance(cookies, list): 23 | for cookie in cookies: 24 | for key, value in cookie.items(): 25 | self._cookies[key] = value 26 | return 27 | for key, value in cookies.items(): 28 | self._cookies[key] = value 29 | 30 | def delete(self, *cookies): 31 | if cookies: 32 | for cookie in cookies: 33 | try: 34 | del self._cookies[cookie] 35 | except KeyError: 36 | pass 37 | else: 38 | self._cookies.clear() 39 | 40 | def all(self, verbose=False): 41 | cookies = {} 42 | for key, value in self._cookies.items(): 43 | cookies[key] = value 44 | return cookies 45 | 46 | def __getitem__(self, item): 47 | return self._cookies[item].value 48 | 49 | def __contains__(self, key): 50 | return key in self._cookies 51 | 52 | def __eq__(self, other_object): 53 | if isinstance(other_object, dict): 54 | cookies_dict = dict( 55 | [(key, morsel.value) for key, morsel in self._cookies.items()] 56 | ) 57 | return cookies_dict == other_object 58 | return False 59 | 60 | 61 | class DjangoClient(LxmlDriver): 62 | 63 | driver_name = "django" 64 | 65 | def __init__(self, user_agent=None, wait_time=2, **kwargs): 66 | from django.test.client import Client 67 | 68 | self._custom_headers = kwargs.pop("custom_headers", {}) 69 | 70 | client_kwargs = {} 71 | for key, value in six.iteritems(kwargs): 72 | if key.startswith("client_"): 73 | client_kwargs[key.replace("client_", "")] = value 74 | 75 | self._browser = Client(**client_kwargs) 76 | self._user_agent = user_agent 77 | self._cookie_manager = CookieManager(self._browser.cookies) 78 | super(DjangoClient, self).__init__(wait_time=wait_time) 79 | 80 | def __enter__(self): 81 | return self 82 | 83 | def __exit__(self, exc_type, exc_value, traceback): 84 | pass 85 | 86 | def _post_load(self): 87 | self._forms = {} 88 | try: 89 | del self._html 90 | except AttributeError: 91 | pass 92 | self.status_code = StatusCode(self._response.status_code, "") 93 | 94 | def _handle_redirect_chain(self): 95 | if self._response.redirect_chain: 96 | for redirect_url, redirect_code in self._response.redirect_chain: 97 | self._last_urls.append(redirect_url) 98 | self._url = self._last_urls[-1] 99 | 100 | def _set_extra_params(self, url): 101 | extra = {} 102 | components = parse.urlparse(url) 103 | if components.hostname: 104 | extra.update({"SERVER_NAME": components.hostname}) 105 | if components.port: 106 | extra.update({"SERVER_PORT": components.port}) 107 | if self._user_agent: 108 | extra.update({"User-Agent": self._user_agent}) 109 | if self._custom_headers: 110 | extra.update(self._custom_headers) 111 | return extra 112 | 113 | def _do_method(self, method, url, data=None): 114 | self._url = url 115 | extra = self._set_extra_params(url) 116 | func_method = getattr(self._browser, method.lower()) 117 | self._response = func_method(url, data=data, follow=True, **extra) 118 | self._last_urls.append(url) 119 | self._handle_redirect_chain() 120 | self._post_load() 121 | 122 | def submit_data(self, form): 123 | return super(DjangoClient, self).submit(form).content 124 | 125 | @property 126 | def html(self): 127 | return self._response.content.decode(self._response._charset or "utf-8") 128 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/driver/element_present.py: -------------------------------------------------------------------------------- 1 | class ElementPresentMixIn(object): 2 | """ Support is_element_present_by_* methods for non-javascript drivers. """ 3 | 4 | def is_element_present_by_css(self, css_selector, wait_time=None): 5 | return bool(self.find_by_css(css_selector)) 6 | 7 | def is_element_not_present_by_css(self, css_selector, wait_time=None): 8 | return not self.is_element_present_by_css(css_selector, wait_time) 9 | 10 | def is_element_present_by_xpath(self, xpath, wait_time=None): 11 | return bool(self.find_by_xpath(xpath)) 12 | 13 | def is_element_not_present_by_xpath(self, xpath, wait_time=None): 14 | return not self.is_element_present_by_xpath(xpath, wait_time) 15 | 16 | def is_element_present_by_tag(self, tag, wait_time=None): 17 | return bool(self.find_by_tag(tag)) 18 | 19 | def is_element_not_present_by_tag(self, tag, wait_time=None): 20 | return not self.is_element_present_by_tag(tag, wait_time) 21 | 22 | def is_element_present_by_name(self, name, wait_time=None): 23 | return bool(self.find_by_name(name)) 24 | 25 | def is_element_not_present_by_name(self, name, wait_time=None): 26 | return not self.is_element_present_by_name(name, wait_time) 27 | 28 | def is_element_present_by_value(self, value, wait_time=None): 29 | return bool(self.find_by_value(value)) 30 | 31 | def is_element_not_present_by_value(self, value, wait_time=None): 32 | return not self.is_element_present_by_value(value, wait_time) 33 | 34 | def is_element_present_by_text(self, text, wait_time=None): 35 | return bool(self.find_by_text(text)) 36 | 37 | def is_element_not_present_by_text(self, text, wait_time=None): 38 | return not self.is_element_present_by_text(text, wait_time) 39 | 40 | def is_element_present_by_id(self, id, wait_time=None): 41 | return bool(self.find_by_id(id)) 42 | 43 | def is_element_not_present_by_id(self, id, wait_time=None): 44 | return not self.is_element_present_by_id(id, wait_time) 45 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/driver/flaskclient.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2014 splinter authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | from __future__ import with_statement 8 | 9 | from splinter.cookie_manager import CookieManagerAPI 10 | from splinter.request_handler.status_code import StatusCode 11 | 12 | from .lxmldriver import LxmlDriver 13 | 14 | 15 | class CookieManager(CookieManagerAPI): 16 | def __init__(self, browser_cookies): 17 | self._cookies = browser_cookies 18 | 19 | def add(self, cookies): 20 | if isinstance(cookies, list): 21 | for cookie in cookies: 22 | for key, value in cookie.items(): 23 | self._cookies.set_cookie("localhost", key, value) 24 | return 25 | for key, value in cookies.items(): 26 | self._cookies.set_cookie("localhost", key, value) 27 | 28 | def delete(self, *cookies): 29 | if cookies: 30 | for cookie in cookies: 31 | try: 32 | self._cookies.delete_cookie("localhost", cookie) 33 | except KeyError: 34 | pass 35 | else: 36 | self._cookies.cookie_jar.clear() 37 | 38 | def all(self, verbose=False): 39 | cookies = {} 40 | for cookie in self._cookies.cookie_jar: 41 | cookies[cookie.name] = cookie.value 42 | return cookies 43 | 44 | def __getitem__(self, item): 45 | cookies = dict([(c.name, c) for c in self._cookies.cookie_jar]) 46 | return cookies[item].value 47 | 48 | def __contains__(self, key): 49 | for cookie in self._cookies.cookie_jar: 50 | if cookie.name == key: 51 | return True 52 | return False 53 | 54 | def __eq__(self, other_object): 55 | if isinstance(other_object, dict): 56 | cookies_dict = dict([(c.name, c.value) for c in self._cookies.cookie_jar]) 57 | return cookies_dict == other_object 58 | return False 59 | 60 | class FlaskClient(LxmlDriver): 61 | 62 | driver_name = "flask" 63 | 64 | def __init__(self, app, user_agent=None, wait_time=2, custom_headers=None): 65 | app.config["TESTING"] = True 66 | self._browser = app.test_client() 67 | self._cookie_manager = CookieManager(self._browser) 68 | self._custom_headers = custom_headers if custom_headers else {} 69 | super(FlaskClient, self).__init__(wait_time=wait_time) 70 | 71 | def __enter__(self): 72 | return self 73 | 74 | def __exit__(self, exc_type, exc_value, traceback): 75 | pass 76 | 77 | def _post_load(self): 78 | self._forms = {} 79 | try: 80 | del self._html 81 | except AttributeError: 82 | pass 83 | self.status_code = StatusCode(self._response.status_code, "") 84 | 85 | def _do_method(self, method, url, data=None): 86 | self._url = url 87 | func_method = getattr(self._browser, method.lower()) 88 | while True: 89 | self._last_urls.append(url) 90 | # flask doesn't expose redirect_chain, so we have to mark it 91 | self._response = func_method( 92 | url, headers=self._custom_headers, data=data, follow_redirects=False 93 | ) 94 | if self._response.status_code not in (301, 302, 303, 305, 307): 95 | break 96 | url = self._response.headers["Location"] 97 | self._url = self._last_urls[-1] 98 | self._post_load() 99 | 100 | def submit_data(self, form): 101 | return super(FlaskClient, self).submit(form).data 102 | 103 | @property 104 | def html(self): 105 | return self._response.get_data(as_text=True) 106 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/driver/webdriver/chrome.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2012 splinter authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | from selenium.webdriver import Chrome 8 | from selenium.webdriver.chrome.options import Options 9 | from splinter.driver.webdriver import BaseWebDriver, WebDriverElement 10 | from splinter.driver.webdriver.cookie_manager import CookieManager 11 | 12 | 13 | class WebDriver(BaseWebDriver): 14 | 15 | driver_name = "Chrome" 16 | 17 | def __init__( 18 | self, 19 | options=None, 20 | user_agent=None, 21 | wait_time=2, 22 | fullscreen=False, 23 | incognito=False, 24 | headless=False, 25 | **kwargs 26 | ): 27 | 28 | options = Options() if options is None else options 29 | 30 | if user_agent is not None: 31 | options.add_argument("--user-agent=" + user_agent) 32 | 33 | if incognito: 34 | options.add_argument("--incognito") 35 | 36 | if fullscreen: 37 | options.add_argument("--kiosk") 38 | 39 | if headless: 40 | options.add_argument("--headless") 41 | options.add_argument("--disable-gpu") 42 | 43 | self.driver = Chrome(options=options, **kwargs) 44 | 45 | self.element_class = WebDriverElement 46 | 47 | self._cookie_manager = CookieManager(self.driver) 48 | 49 | super(WebDriver, self).__init__(wait_time) 50 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/driver/webdriver/cookie_manager.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2012 splinter authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | import sys 7 | 8 | from splinter.cookie_manager import CookieManagerAPI 9 | 10 | if sys.version_info[0] > 2: 11 | from urllib.parse import urlparse 12 | else: 13 | from urlparse import urlparse # NOQA 14 | 15 | 16 | class CookieManager(CookieManagerAPI): 17 | def __init__(self, driver): 18 | self.driver = driver 19 | 20 | def add(self, cookies): 21 | if isinstance(cookies, list): 22 | for cookie in cookies: 23 | for key, value in cookie.items(): 24 | self.driver.add_cookie({"name": key, "value": value}) 25 | return 26 | for key, value in cookies.items(): 27 | self.driver.add_cookie({"name": key, "value": value}) 28 | 29 | def delete(self, *cookies): 30 | if cookies: 31 | for cookie in cookies: 32 | self.driver.delete_cookie(cookie) 33 | else: 34 | self.driver.delete_all_cookies() 35 | 36 | def all(self, verbose=False): 37 | if not verbose: 38 | cleaned_cookies = {} 39 | cookies = self.driver.get_cookies() 40 | for cookie in cookies: 41 | if not cookie["domain"].startswith("."): 42 | cookie_domain = cookie["domain"] 43 | else: 44 | cookie_domain = cookie["domain"][1:] 45 | 46 | if cookie_domain in urlparse(self.driver.current_url).netloc: 47 | cleaned_cookies[cookie["name"]] = cookie["value"] 48 | 49 | return cleaned_cookies 50 | return self.driver.get_cookies() 51 | 52 | def __getitem__(self, item): 53 | return self.driver.get_cookie(item)["value"] 54 | 55 | def __contains__(self, key): 56 | return self.driver.get_cookie(key) is not None 57 | 58 | def __eq__(self, other_object): 59 | cookies = {} 60 | for cookie in self.driver.get_cookies(): 61 | cookies[cookie["name"]] = cookie["value"] 62 | 63 | if isinstance(other_object, dict): 64 | return dict(cookies) == other_object 65 | 66 | return False 67 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/driver/webdriver/firefox.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2012 splinter authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | import os 7 | 8 | from selenium.webdriver import DesiredCapabilities, Firefox 9 | from selenium.webdriver.firefox.firefox_profile import FirefoxProfile 10 | from splinter.driver.webdriver import ( 11 | BaseWebDriver, 12 | WebDriverElement as WebDriverElement, 13 | ) 14 | from splinter.driver.webdriver.cookie_manager import CookieManager 15 | from selenium.webdriver.common.keys import Keys 16 | from selenium.webdriver.common.action_chains import ActionChains 17 | from selenium.webdriver.firefox.firefox_binary import FirefoxBinary 18 | from selenium.webdriver.firefox.options import Options 19 | 20 | 21 | class WebDriver(BaseWebDriver): 22 | 23 | driver_name = "Firefox" 24 | 25 | def __init__( 26 | self, 27 | profile=None, 28 | extensions=None, 29 | user_agent=None, 30 | profile_preferences=None, 31 | fullscreen=False, 32 | wait_time=2, 33 | timeout=90, 34 | capabilities=None, 35 | headless=False, 36 | incognito=False, 37 | **kwargs 38 | ): 39 | 40 | firefox_profile = FirefoxProfile(profile) 41 | firefox_profile.set_preference("extensions.logging.enabled", False) 42 | firefox_profile.set_preference("network.dns.disableIPv6", False) 43 | 44 | firefox_capabilities = DesiredCapabilities().FIREFOX 45 | firefox_capabilities["marionette"] = True 46 | 47 | firefox_options = Options() 48 | 49 | if capabilities: 50 | for key, value in capabilities.items(): 51 | firefox_capabilities[key] = value 52 | 53 | if user_agent is not None: 54 | firefox_profile.set_preference("general.useragent.override", user_agent) 55 | 56 | if profile_preferences: 57 | for key, value in profile_preferences.items(): 58 | firefox_profile.set_preference(key, value) 59 | 60 | if extensions: 61 | for extension in extensions: 62 | firefox_profile.add_extension(extension) 63 | 64 | if headless: 65 | os.environ.update({"MOZ_HEADLESS": "1"}) 66 | binary = FirefoxBinary() 67 | binary.add_command_line_options("-headless") 68 | kwargs["firefox_binary"] = binary 69 | 70 | if incognito: 71 | firefox_options.add_argument("-private") 72 | 73 | self.driver = Firefox( 74 | firefox_profile, 75 | capabilities=firefox_capabilities, 76 | options=firefox_options, 77 | timeout=timeout, 78 | **kwargs 79 | ) 80 | 81 | if fullscreen: 82 | ActionChains(self.driver).send_keys(Keys.F11).perform() 83 | 84 | self.element_class = WebDriverElement 85 | 86 | self._cookie_manager = CookieManager(self.driver) 87 | 88 | super(WebDriver, self).__init__(wait_time) 89 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/driver/webdriver/remote.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2013 splinter authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | from selenium.webdriver import Remote 8 | from selenium.webdriver.common.desired_capabilities import DesiredCapabilities 9 | from splinter.driver.webdriver import ( 10 | BaseWebDriver, 11 | WebDriverElement as BaseWebDriverElement, 12 | ) 13 | from splinter.driver.webdriver.cookie_manager import CookieManager 14 | 15 | 16 | class WebDriver(BaseWebDriver): 17 | 18 | driver_name = "remote" 19 | # TODO: This constant belongs in selenium.webdriver.Remote 20 | DEFAULT_URL = "http://127.0.0.1:4444/wd/hub" 21 | 22 | def __init__(self, url=DEFAULT_URL, browser="firefox", wait_time=2, **ability_args): 23 | browsername = browser.upper() 24 | # Handle case where user specifies IE with a space in it 25 | if browsername == "INTERNET EXPLORER": 26 | browsername = "INTERNETEXPLORER" 27 | abilities = getattr(DesiredCapabilities, browsername, {}) 28 | abilities.update(ability_args) 29 | 30 | self.driver = Remote(url, abilities) 31 | 32 | self.element_class = WebDriverElement 33 | 34 | self._cookie_manager = CookieManager(self.driver) 35 | 36 | super(WebDriver, self).__init__(wait_time) 37 | 38 | 39 | class WebDriverElement(BaseWebDriverElement): 40 | def mouse_over(self): 41 | """ 42 | Remote Firefox doesn't support mouseover. 43 | """ 44 | raise NotImplementedError("Remote Firefox doesn't support mouse over") 45 | 46 | def mouse_out(self): 47 | """ 48 | Remote Firefox doesn't support mouseout. 49 | """ 50 | raise NotImplementedError("Remote Firefox doesn't support mouseout") 51 | 52 | def double_click(self): 53 | """ 54 | Remote Firefox doesn't support doubleclick. 55 | """ 56 | raise NotImplementedError("Remote Firefox doesn't support doubleclick") 57 | 58 | def right_click(self): 59 | """ 60 | Remote Firefox doesn't support right click' 61 | """ 62 | raise NotImplementedError("Remote Firefox doesn't support right click") 63 | 64 | def drag_and_drop(self, droppable): 65 | """ 66 | Remote Firefox doesn't support drag and drop 67 | """ 68 | raise NotImplementedError("Remote Firefox doesn't support drag an drop") 69 | 70 | mouseover = mouse_over 71 | mouseout = mouse_out 72 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/element_list.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2012 splinter authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | from splinter.exceptions import ElementDoesNotExist 8 | 9 | 10 | class ElementList(list): 11 | """ 12 | List of elements. Each member of the list is (usually) an instance 13 | of :class:`ElementAPI `. 14 | 15 | Beyond the traditional list methods, the ``ElementList`` provides some 16 | other methods, listed below. 17 | 18 | There is a peculiar behavior on ElementList: you never get an 19 | ``IndexError``. Instead, you can an :class:`ElementDoesNotExist 20 | ` exception when trying to 21 | access an inexistent item in the list: 22 | 23 | >>> element_list = ElementList([]) 24 | >>> element_list[0] # raises ElementDoesNotExist 25 | """ 26 | 27 | def __init__(self, list, driver=None, find_by=None, query=None): 28 | """ 29 | Creates the list. 30 | """ 31 | self.extend(list) 32 | self.driver = driver 33 | self.find_by = find_by 34 | self.query = query 35 | 36 | def __getitem__(self, index): 37 | if not isinstance(index, int): 38 | return self.first[index] 39 | try: 40 | return super(ElementList, self).__getitem__(index) 41 | except IndexError: 42 | raise ElementDoesNotExist( 43 | u'no elements could be found with {0} "{1}"'.format( 44 | self.find_by, self.query 45 | ) 46 | ) 47 | 48 | @property 49 | def first(self): 50 | """ 51 | An alias to the first element of the list: 52 | 53 | >>> assert element_list[0] == element_list.first 54 | """ 55 | return self[0] 56 | 57 | @property 58 | def last(self): 59 | """ 60 | An alias to the last element of the list: 61 | 62 | >>> assert element_list[-1] == element_list.last 63 | """ 64 | return self[-1] 65 | 66 | def is_empty(self): 67 | """ 68 | Returns ``True`` if the list is empty. 69 | """ 70 | return len(self) == 0 71 | 72 | def __getattr__(self, name): 73 | try: 74 | return getattr(self.first, name) 75 | except (ElementDoesNotExist, AttributeError): 76 | raise AttributeError( 77 | u"'{0}' object has no attribute '{1}'".format( 78 | self.__class__.__name__, name 79 | ) 80 | ) 81 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/exceptions.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2012 splinter authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | 8 | class DriverNotFoundError(Exception): 9 | """ 10 | Exception raised when a driver is not found. 11 | 12 | Example: 13 | 14 | >>> from splinter import Browser 15 | >>> b = Browser('unknown driver') # raises DriverNotFoundError 16 | """ 17 | 18 | pass 19 | 20 | 21 | class ElementDoesNotExist(Exception): 22 | """ 23 | Exception raised when an element is not found in the page. 24 | 25 | The exception is raised only when someone tries to access the element, 26 | not when the driver is finding it. 27 | 28 | Example: 29 | 30 | >>> elements = browser.find_by_id('unknown-id') # returns an empty list 31 | >>> elements[0] # raises ElementDoesNotExist 32 | """ 33 | 34 | pass 35 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/meta.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2012 splinter authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | 8 | class InheritedDocs(type): 9 | def __new__(mcs, class_name, bases, dict): 10 | items_to_patch = [ 11 | (k, v) for k, v in dict.items() if not k.startswith("__") and not v.__doc__ 12 | ] 13 | for name, obj in items_to_patch: 14 | doc = None 15 | for base in bases: 16 | if hasattr(base, name): 17 | doc = getattr(base, name).__doc__ 18 | 19 | if doc: 20 | if isinstance(obj, property) and not obj.fset: 21 | obj.fget.__doc__ = doc 22 | dict[name] = property(fget=obj.fget) 23 | else: 24 | obj.__doc__ = doc 25 | break 26 | 27 | return type.__new__(mcs, class_name, bases, dict) 28 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/request_handler/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2012 splinter authors. All rights reserved. 2 | # Use of this source code is governed by a BSD-style 3 | # license that can be found in the LICENSE file. 4 | -------------------------------------------------------------------------------- /browser_chrome_auto_tool/splinter/request_handler/status_code.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2012 splinter authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | 8 | class StatusCode(object): 9 | def __init__(self, status_code, reason): 10 | #: A message for the response (example: Success) 11 | self.reason = reason 12 | #: Code of the response (example: 200) 13 | self.code = status_code 14 | 15 | def __eq__(self, other): 16 | return self.code == other 17 | 18 | def __ne__(self, other): 19 | return not self.__eq__(other) 20 | 21 | def __str__(self): 22 | return "{} - {}".format(self.code, self.reason) 23 | 24 | def is_success(self): 25 | """ 26 | Returns ``True`` if the response was succeed, otherwise, returns ``False``. 27 | """ 28 | return self.code < 400 29 | -------------------------------------------------------------------------------- /decompile_apk/APKs/1/gat5sj99900909b.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/decompile_apk/APKs/1/gat5sj99900909b.apk -------------------------------------------------------------------------------- /decompile_apk/apktool.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | if "%PATH_BASE%" == "" set PATH_BASE=%PATH% 3 | set PATH=%CD%;%PATH_BASE%; 4 | chcp 65001 2>nul >nul 5 | java -jar -Duser.language=en -Dfile.encoding=UTF8 "%~dp0\apktool.jar" %* 6 | -------------------------------------------------------------------------------- /decompile_apk/apktool.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/decompile_apk/apktool.jar -------------------------------------------------------------------------------- /decompile_apk/decompiling_apk.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | import os 5 | import zipfile; 6 | import base64; 7 | 8 | # apk 的存储路径 9 | apkPath = u'./APKs/' 10 | 11 | dirlist = os.listdir(apkPath) 12 | 13 | # 用apktool 反编译apk 之后的存储路径 14 | outputPath = u'./apktool_out/' 15 | 16 | 17 | def zip_apk_file_path(input_path, output_path, output_name): 18 | f = zipfile.ZipFile(output_path + '/' + output_name, 'w', zipfile.ZIP_DEFLATED) 19 | filelists = [] 20 | get_zip_file(input_path, filelists) 21 | for file in filelists: 22 | f.write(file); 23 | f.close() 24 | return output_path + r"/" + output_name 25 | 26 | def apkToolFunction(APKPath, APK,apkoutPath): 27 | targetPath=apkoutPath; 28 | cmd = "apktool d -f {0} -o {1}".format(APKPath, targetPath) 29 | os.system(cmd) 30 | output_path=os.path.dirname(targetPath); 31 | zipName=APK+'.zip'; 32 | result= zip_apk_file_path(targetPath,output_path,zipName); 33 | ipa_file_define_name=base64.b64encode(result); 34 | filePath=base64.b64decode(ipa_file_define_name); 35 | directory = os.path.dirname(filePath); 36 | filename = os.path.basename(filePath); 37 | print 'result:'+result; 38 | 39 | def get_zip_file(input_path, result): 40 | files = os.listdir(input_path) 41 | for file in files: 42 | if os.path.isdir(input_path + '/' + file): 43 | get_zip_file(input_path + '/' + file, result) 44 | else: 45 | result.append(input_path + '/' + file) 46 | 47 | for i in range(len(dirlist)): 48 | filelist = apkPath + dirlist[i] 49 | filelist = filelist.decode('gbk'); 50 | apklist = os.listdir(filelist) 51 | category_output = outputPath + dirlist[i] 52 | 53 | if not os.path.exists(category_output): 54 | os.makedirs(category_output) 55 | 56 | for APK in apklist: 57 | portion = os.path.splitext(APK) 58 | apkoutPath = os.path.join(category_output, portion[0]) 59 | result_APK = os.path.join(apkPath + dirlist[i], APK) 60 | # if not os.path.exists(apkoutPath): 61 | # os.makedirs(apkoutPath) 62 | # cmd = "apktool d -f {0} -o {1}".format(APK, apkoutPath) # 反编译出来apk 之后按照文件名在存储 63 | # os.system(cmd) 64 | apkToolFunction(result_APK,APK,apkoutPath); 65 | 66 | 67 | print "all work done!~" 68 | -------------------------------------------------------------------------------- /game_thirdsdk_check.py/Game_ThirdSDK_Check.py.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | 3 | import sys 4 | import os 5 | import subprocess 6 | import time 7 | import shlex 8 | 9 | 10 | # 第三方SDK文件夹目录的父级目录 11 | third_SDK_Root_Path='' 12 | # 第三方SDK名称标示,这里实例说明 13 | third_SDK_Names=['Unity', 14 | 'Admob' 15 | ] 16 | # 第三方SDK文件.a或framework的路径目录,这里实例说明 17 | third_SDK_Paths=['Unity/2.1.1/UnityAds.framework/UnityAds', 18 | 'Admob/7.25.0/GoogleMobileAds.framework/GoogleMobileAds' 19 | ] 20 | 21 | # 调用子进程,拿到输出结果 22 | # @time_me 23 | def startSubprocessPrograme(shell_cmd,check_classValue,platName): 24 | start = time.clock() 25 | # 26 | cmd=shlex.split(shell_cmd) 27 | p=subprocess.Popen(cmd,shell=False,stdout=subprocess.PIPE,stderr=subprocess.STDOUT) 28 | result = False 29 | while p.poll() is None: 30 | line = p.stdout.readline() 31 | line = line.strip() 32 | if check_classValue in line: 33 | result=True 34 | if p.returncode == 0: 35 | 36 | pass 37 | else: 38 | print('subprocess failed : [{}]'.format(shell_cmd)) 39 | print(' 完成 :[{}] SDK查找!!!!'.format(platName)) 40 | if result==True: 41 | print('成功找到SDK: [{}]'.format(platName)) 42 | else: 43 | print('不是 [{}] SDK'.format(platName)) 44 | 45 | end = time.clock() 46 | 47 | print str(end-start) 48 | return result 49 | 50 | # @time_me 51 | def searchFull(search_platName): 52 | result_platname='' 53 | for i in range(len(third_SDK_Names)): 54 | # 组装全路径 55 | platNamePath = third_SDK_Paths[i] 56 | # 可能存在多个路径 57 | arrTemp=platNamePath.split(',') 58 | for j in range(len(arrTemp)): 59 | platNamePath=arrTemp[j] 60 | print(' platNamePath: {}'.format(platNamePath)) 61 | 62 | platFullPath = third_SDK_Root_Path + platNamePath 63 | 64 | targetPath = 'strings {}'.format(platFullPath) 65 | platName = third_SDK_Names[i] 66 | 67 | print(' cmd: {}'.format(targetPath)) 68 | result = startSubprocessPrograme( 69 | targetPath, 70 | search_platName, platName) 71 | 72 | if result == True: 73 | 74 | break; 75 | 76 | if result == True: 77 | result_platname=third_SDK_Names[i] 78 | break; 79 | print('=======') 80 | print('完成SDK查找!!! 目标SDK是:{}'.format(result_platname)) 81 | print('=======') 82 | pass 83 | 84 | if __name__ == '__main__': 85 | paras_len= len(sys.argv) 86 | if paras_len>=2: 87 | third_SDK_Root_Path=sys.argv[1] 88 | search_platName = sys.argv[2] 89 | start = time.clock() 90 | searchFull(search_platName) 91 | end = time.clock() 92 | print str(end-start) 93 | pass -------------------------------------------------------------------------------- /re-sign-ipa/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Python: 当前文件", 9 | "type": "python", 10 | "request": "launch", 11 | "program": "${file}", 12 | "console": "integratedTerminal" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /re-sign-ipa/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.pythonPath": "/usr/bin/python" 3 | } -------------------------------------------------------------------------------- /re-sign-ipa/MachOView-2.4.9200.dmg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/MachOView-2.4.9200.dmg -------------------------------------------------------------------------------- /re-sign-ipa/embedded.mobileprovision: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/embedded.mobileprovision -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/insert_sdks/.DS_Store -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/insert_sdks/Frameworks/.DS_Store -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/GCDWebUploader.bundle/Contents/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/GCDWebUploader.bundle/Contents/Info.plist -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/GCDWebUploader.bundle/Contents/Resources/css/index.css: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2015, Pierre-Olivier Latour 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * The name of Pierre-Olivier Latour may not be used to endorse 13 | or promote products derived from this software without specific 14 | prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | .row-file { 29 | height: 40px; 30 | } 31 | 32 | .column-icon { 33 | width: 40px; 34 | text-align: center; 35 | } 36 | 37 | .column-name { 38 | } 39 | 40 | .column-size { 41 | width: 100px; 42 | text-align: right; 43 | } 44 | 45 | .column-move { 46 | width: 40px; 47 | text-align: center; 48 | } 49 | 50 | .column-delete { 51 | width: 40px; 52 | text-align: center; 53 | } 54 | 55 | .column-path { 56 | } 57 | 58 | .column-progress { 59 | width: 200px; 60 | } 61 | 62 | .footer { 63 | color: #999; 64 | text-align: center; 65 | font-size: 0.9em; 66 | } 67 | 68 | #reload { 69 | float: right; 70 | } 71 | 72 | #create-input { 73 | width: 50%; 74 | height: 20px; 75 | } 76 | 77 | #move-input { 78 | width: 80%; 79 | height: 20px; 80 | } 81 | 82 | /* Bootstrap overrides */ 83 | 84 | .btn:focus { 85 | outline: none; /* FIXME: Work around for Chrome only but still draws focus ring while button pressed */ 86 | } 87 | 88 | .btn-toolbar { 89 | margin-top: 30px; 90 | margin-bottom: 20px; 91 | } 92 | 93 | .table .progress { 94 | margin-top: 0px; 95 | margin-bottom: 0px; 96 | height: 16px; 97 | } 98 | 99 | .panel-default > .panel-heading { 100 | color: #555; 101 | } 102 | 103 | .breadcrumb { 104 | background-color: transparent; 105 | border-radius: 0px; 106 | margin-bottom: 0px; 107 | padding: 0px; 108 | } 109 | 110 | .breadcrumb > .active { 111 | color: #555; 112 | } 113 | 114 | .breadcrumb > li + li:before { 115 | color: #999; 116 | } 117 | 118 | .table > tbody > tr > td { 119 | vertical-align: middle; 120 | } 121 | 122 | .table > tbody > tr > td > p { 123 | margin: 0px; 124 | } 125 | 126 | /* Initial state */ 127 | 128 | .uploading { 129 | display: none; 130 | } 131 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/GCDWebUploader.bundle/Contents/Resources/css/jquery.fileupload.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* 3 | * jQuery File Upload Plugin CSS 1.3.0 4 | * https://github.com/blueimp/jQuery-File-Upload 5 | * 6 | * Copyright 2013, Sebastian Tschan 7 | * https://blueimp.net 8 | * 9 | * Licensed under the MIT license: 10 | * http://www.opensource.org/licenses/MIT 11 | */ 12 | 13 | .fileinput-button { 14 | position: relative; 15 | overflow: hidden; 16 | } 17 | .fileinput-button input { 18 | position: absolute; 19 | top: 0; 20 | right: 0; 21 | margin: 0; 22 | opacity: 0; 23 | -ms-filter: 'alpha(opacity=0)'; 24 | font-size: 200px; 25 | direction: ltr; 26 | cursor: pointer; 27 | } 28 | 29 | /* Fixes for IE < 8 */ 30 | @media screen\9 { 31 | .fileinput-button input { 32 | filter: alpha(opacity=0); 33 | font-size: 100%; 34 | height: 100%; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/GCDWebUploader.bundle/Contents/Resources/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | "PROLOGUE" = "

Drag & drop files on this window or use the \"Upload Files…\" button to upload new files.

"; 2 | "EPILOGUE" = ""; 3 | "FOOTER_FORMAT" = "%@ %@"; 4 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/GCDWebUploader.bundle/Contents/Resources/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/GCDWebUploader.bundle/Contents/Resources/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/GCDWebUploader.bundle/Contents/Resources/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/GCDWebUploader.bundle/Contents/Resources/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/GCDWebUploader.bundle/Contents/Resources/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/GCDWebUploader.bundle/Contents/Resources/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/GCDWebUploader.bundle/Contents/Resources/js/html5shiv.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); 5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; 6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| 7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f); 8 | if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d #mq-test-1 { width: 42px; }',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b&"'\x00]/g,b.encMap={"<":"<",">":">","&":"&",'"':""","'":"'"},b.encode=function(a){return(null==a?"":""+a).replace(b.encReg,function(a){return b.encMap[a]||""})},b.arg="o",b.helper=",print=function(s,e){_s+=e?(s==null?'':s):_e(s);},include=function(s,d){_s+=tmpl(s,d);}","function"==typeof define&&define.amd?define(function(){return b}):a.tmpl=b}(this); -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/Headers/MobGiAdsToolModule.h: -------------------------------------------------------------------------------- 1 | // 2 | // MobGiAdsToolModule.h 3 | // MobGiAdsToolModule 4 | // 5 | // Created by star.liao on 2018/4/16. 6 | // Copyright © 2018年 com.idreamsky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for MobGiAdsToolModule. 12 | FOUNDATION_EXPORT double MobGiAdsToolModuleVersionNumber; 13 | 14 | //! Project version string for MobGiAdsToolModule. 15 | FOUNDATION_EXPORT const unsigned char MobGiAdsToolModuleVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/Info.plist -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/MobGiAdsToolModule: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/MobGiAdsToolModule -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/MobGiAdsToolModule.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module MobGiAdsToolModule { 2 | umbrella header "MobGiAdsToolModule.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/AFAutoPurgingImageCache.h: -------------------------------------------------------------------------------- 1 | // AFAutoPurgingImageCache.h 2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import 23 | #import 24 | 25 | #if TARGET_OS_IOS || TARGET_OS_TV 26 | #import 27 | 28 | NS_ASSUME_NONNULL_BEGIN 29 | 30 | /** 31 | The `AFImageCache` protocol defines a set of APIs for adding, removing and fetching images from a cache synchronously. 32 | */ 33 | @protocol AFImageCache 34 | 35 | /** 36 | Adds the image to the cache with the given identifier. 37 | 38 | @param image The image to cache. 39 | @param identifier The unique identifier for the image in the cache. 40 | */ 41 | - (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier; 42 | 43 | /** 44 | Removes the image from the cache matching the given identifier. 45 | 46 | @param identifier The unique identifier for the image in the cache. 47 | 48 | @return A BOOL indicating whether or not the image was removed from the cache. 49 | */ 50 | - (BOOL)removeImageWithIdentifier:(NSString *)identifier; 51 | 52 | /** 53 | Removes all images from the cache. 54 | 55 | @return A BOOL indicating whether or not all images were removed from the cache. 56 | */ 57 | - (BOOL)removeAllImages; 58 | 59 | /** 60 | Returns the image in the cache associated with the given identifier. 61 | 62 | @param identifier The unique identifier for the image in the cache. 63 | 64 | @return An image for the matching identifier, or nil. 65 | */ 66 | - (nullable UIImage *)imageWithIdentifier:(NSString *)identifier; 67 | @end 68 | 69 | 70 | /** 71 | The `ImageRequestCache` protocol extends the `ImageCache` protocol by adding methods for adding, removing and fetching images from a cache given an `NSURLRequest` and additional identifier. 72 | */ 73 | @protocol AFImageRequestCache 74 | 75 | /** 76 | Adds the image to the cache using an identifier created from the request and additional identifier. 77 | 78 | @param image The image to cache. 79 | @param request The unique URL request identifing the image asset. 80 | @param identifier The additional identifier to apply to the URL request to identify the image. 81 | */ 82 | - (void)addImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier; 83 | 84 | /** 85 | Removes the image from the cache using an identifier created from the request and additional identifier. 86 | 87 | @param request The unique URL request identifing the image asset. 88 | @param identifier The additional identifier to apply to the URL request to identify the image. 89 | 90 | @return A BOOL indicating whether or not all images were removed from the cache. 91 | */ 92 | - (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier; 93 | 94 | /** 95 | Returns the image from the cache associated with an identifier created from the request and additional identifier. 96 | 97 | @param request The unique URL request identifing the image asset. 98 | @param identifier The additional identifier to apply to the URL request to identify the image. 99 | 100 | @return An image for the matching request and identifier, or nil. 101 | */ 102 | - (nullable UIImage *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier; 103 | 104 | @end 105 | 106 | /** 107 | The `AutoPurgingImageCache` in an in-memory image cache used to store images up to a given memory capacity. When the memory capacity is reached, the image cache is sorted by last access date, then the oldest image is continuously purged until the preferred memory usage after purge is met. Each time an image is accessed through the cache, the internal access date of the image is updated. 108 | */ 109 | @interface AFAutoPurgingImageCache : NSObject 110 | 111 | /** 112 | The total memory capacity of the cache in bytes. 113 | */ 114 | @property (nonatomic, assign) UInt64 memoryCapacity; 115 | 116 | /** 117 | The preferred memory usage after purge in bytes. During a purge, images will be purged until the memory capacity drops below this limit. 118 | */ 119 | @property (nonatomic, assign) UInt64 preferredMemoryUsageAfterPurge; 120 | 121 | /** 122 | The current total memory usage in bytes of all images stored within the cache. 123 | */ 124 | @property (nonatomic, assign, readonly) UInt64 memoryUsage; 125 | 126 | /** 127 | Initialies the `AutoPurgingImageCache` instance with default values for memory capacity and preferred memory usage after purge limit. `memoryCapcity` defaults to `100 MB`. `preferredMemoryUsageAfterPurge` defaults to `60 MB`. 128 | 129 | @return The new `AutoPurgingImageCache` instance. 130 | */ 131 | - (instancetype)init; 132 | 133 | /** 134 | Initialies the `AutoPurgingImageCache` instance with the given memory capacity and preferred memory usage 135 | after purge limit. 136 | 137 | @param memoryCapacity The total memory capacity of the cache in bytes. 138 | @param preferredMemoryCapacity The preferred memory usage after purge in bytes. 139 | 140 | @return The new `AutoPurgingImageCache` instance. 141 | */ 142 | - (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity; 143 | 144 | @end 145 | 146 | NS_ASSUME_NONNULL_END 147 | 148 | #endif 149 | 150 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/AFHTTPSessionManagerAdapter.h: -------------------------------------------------------------------------------- 1 | // 2 | // AFHTTPSessionManagerAdapter.h 3 | // SDKCommonModule 4 | // 5 | // Created by star.liao on 2017/4/1. 6 | // Copyright © 2017年 com.idreamsky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AFHTTPSessionManager.h" 11 | 12 | @interface AFHTTPSessionManagerAdapter : AFHTTPSessionManager 13 | 14 | +(AFHTTPSessionManager *)sharedManager; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/AFNetworkActivityIndicatorManager.h: -------------------------------------------------------------------------------- 1 | // AFNetworkActivityIndicatorManager.h 2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import 23 | 24 | #import 25 | 26 | #if TARGET_OS_IOS 27 | 28 | #import 29 | 30 | NS_ASSUME_NONNULL_BEGIN 31 | 32 | /** 33 | `AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a session task has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero. 34 | 35 | You should enable the shared instance of `AFNetworkActivityIndicatorManager` when your application finishes launching. In `AppDelegate application:didFinishLaunchingWithOptions:` you can do so with the following code: 36 | 37 | [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES]; 38 | 39 | By setting `enabled` to `YES` for `sharedManager`, the network activity indicator will show and hide automatically as requests start and finish. You should not ever need to call `incrementActivityCount` or `decrementActivityCount` yourself. 40 | 41 | See the Apple Human Interface Guidelines section about the Network Activity Indicator for more information: 42 | http://developer.apple.com/library/iOS/#documentation/UserExperience/Conceptual/MobileHIG/UIElementGuidelines/UIElementGuidelines.html#//apple_ref/doc/uid/TP40006556-CH13-SW44 43 | */ 44 | NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.") 45 | @interface AFNetworkActivityIndicatorManager : NSObject 46 | 47 | /** 48 | A Boolean value indicating whether the manager is enabled. 49 | 50 | If YES, the manager will change status bar network activity indicator according to network operation notifications it receives. The default value is NO. 51 | */ 52 | @property (nonatomic, assign, getter = isEnabled) BOOL enabled; 53 | 54 | /** 55 | A Boolean value indicating whether the network activity indicator manager is currently active. 56 | */ 57 | @property (readonly, nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible; 58 | 59 | /** 60 | A time interval indicating the minimum duration of networking activity that should occur before the activity indicator is displayed. The default value 1 second. If the network activity indicator should be displayed immediately when network activity occurs, this value should be set to 0 seconds. 61 | 62 | Apple's HIG describes the following: 63 | 64 | > Display the network activity indicator to provide feedback when your app accesses the network for more than a couple of seconds. If the operation finishes sooner than that, you don’t have to show the network activity indicator, because the indicator is likely to disappear before users notice its presence. 65 | 66 | */ 67 | @property (nonatomic, assign) NSTimeInterval activationDelay; 68 | 69 | /** 70 | A time interval indicating the duration of time of no networking activity required before the activity indicator is disabled. This allows for continuous display of the network activity indicator across multiple requests. The default value is 0.17 seconds. 71 | */ 72 | 73 | @property (nonatomic, assign) NSTimeInterval completionDelay; 74 | 75 | /** 76 | Returns the shared network activity indicator manager object for the system. 77 | 78 | @return The systemwide network activity indicator manager. 79 | */ 80 | + (instancetype)sharedManager; 81 | 82 | /** 83 | Increments the number of active network requests. If this number was zero before incrementing, this will start animating the status bar network activity indicator. 84 | */ 85 | - (void)incrementActivityCount; 86 | 87 | /** 88 | Decrements the number of active network requests. If this number becomes zero after decrementing, this will stop animating the status bar network activity indicator. 89 | */ 90 | - (void)decrementActivityCount; 91 | 92 | /** 93 | Set the a custom method to be executed when the network activity indicator manager should be hidden/shown. By default, this is null, and the UIApplication Network Activity Indicator will be managed automatically. If this block is set, it is the responsiblity of the caller to manager the network activity indicator going forward. 94 | 95 | @param block A block to be executed when the network activity indicator status changes. 96 | */ 97 | - (void)setNetworkingActivityActionWithBlock:(nullable void (^)(BOOL networkActivityIndicatorVisible))block; 98 | 99 | @end 100 | 101 | NS_ASSUME_NONNULL_END 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/AFNetworkReachabilityManagerAdapter.h: -------------------------------------------------------------------------------- 1 | // 2 | // AFNetworkReachabilityManagerAdapter.h 3 | // SDKCommonModule 4 | // 5 | // Created by star.liao on 2017/4/12. 6 | // Copyright © 2017年 com.idreamsky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AFNetworkReachabilityManager.h" 11 | 12 | @interface AFNetworkReachabilityManagerAdapter : AFNetworkReachabilityManager 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/AFNetworking.h: -------------------------------------------------------------------------------- 1 | // AFNetworking.h 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com/) 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 13 | // all 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 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #import 25 | #import 26 | 27 | #ifndef _AFNETWORKING_ 28 | #define _AFNETWORKING_ 29 | 30 | #import "AFURLRequestSerialization.h" 31 | #import "AFURLResponseSerialization.h" 32 | #import "AFSecurityPolicy.h" 33 | 34 | #if !TARGET_OS_WATCH 35 | #import "AFNetworkReachabilityManager.h" 36 | #endif 37 | 38 | #import "AFURLSessionManager.h" 39 | #import "AFHTTPSessionManager.h" 40 | 41 | #endif /* _AFNETWORKING_ */ 42 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/BasicUtilTools.h: -------------------------------------------------------------------------------- 1 | // 2 | // BasicUtilTools.h 3 | // SDKCommonModule 4 | // 5 | // Created by star.liao on 2017/4/1. 6 | // Copyright © 2017年 com.idreamsky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | @interface BasicUtilTools : NSObject 14 | 15 | +(void)clearCache:(NSString *)path; 16 | /** 17 | * 初始化获取一些耗时的参数 18 | */ 19 | +(void) initBasicParas; 20 | 21 | //获取当前屏幕的尺寸 22 | + (CGSize)fixedScreenSize; 23 | 24 | //Generanl-Version 25 | +(NSString*) appVersion; 26 | 27 | //Generanl-Build 28 | +(NSString*) CFBundleVersion; 29 | 30 | //包体标识符 31 | +(NSString*) CFBundleIdentifier; 32 | 33 | +(BOOL) isNetEnable; 34 | 35 | //网络类型 @"wifi",@"2G",@"3G", @"4G",@"" 36 | +(NSString*) getNetType; 37 | 38 | //网络类型 1:wifi,2:2G,3:3G, 4:4G 0:未知 39 | +(int) getNetTypeInt; 40 | 41 | +(NSString*) getCarrierName; 42 | //运营商; 1:联通,2:电信,3:移动,0:其他 43 | +(int) getCarrierIntName; 44 | 45 | +(NSString*) udid; 46 | 47 | +(NSString*) uuid; 48 | 49 | +(NSString*) idfv; 50 | 51 | +(NSString*) idfa; 52 | 53 | +(BOOL) isIphoneX; 54 | 55 | +(NSString*) lang; 56 | 57 | //获取iOS设备机型号 58 | + (NSString*)deviceVersion; 59 | 60 | +(NSString*)generateCrypt_str:(NSMutableDictionary*)dictionary; 61 | 62 | +(BOOL) isPortrait; 63 | 64 | +(NSString *)getResolutionStr; 65 | 66 | //获取iOS系统版本号,IOS9 67 | +(NSString*)getSystemVersion; 68 | 69 | +(NSString *)generateMD5Str:(NSString*)str; 70 | 71 | //获取iOS设备品牌标示定义,@"1"=>iphone,@"8"=>ipad,@"9"=>ipod 72 | +(NSString*) getDeviceDes; 73 | 74 | +(NSString*)ledouUUID; 75 | 76 | +(NSString*) getUA; 77 | 78 | + (float)getIOSVersion; 79 | 80 | + (NSString*)getIOSVersionStr; 81 | 82 | +(NSString*) getNetWorkTypeStr; 83 | 84 | +(NSUInteger) checkDeviceOrientation; 85 | 86 | +(NSDate*) getDateFromTimestamp:(NSString*)timeStamp; 87 | 88 | +(NSDate*) getBeijingDateFromTimestamp:(NSString*)timeStamp; 89 | 90 | //获取当前时间-北京时间 91 | +(NSDate*) getCurrentBeijingDate; 92 | 93 | //获取当前服务端时间戳 94 | +(NSString*) getCurrentServerTimeStamp:(NSString*)headerDateStr; 95 | 96 | //获取当前服务端UTC时间 97 | +(NSDate*) getCurrentServerUTCDate:(NSString*)headerDateStr; 98 | 99 | //获取当前服务端时间-北京时间 100 | +(NSDate*) getCurrentServerBeijingDate:(NSString*)headerDateStr; 101 | 102 | //获取当前系统时间 103 | +(NSDate*) getCurrentSystemUTCDate; 104 | 105 | //获取两个时间戳的差值,返回值以毫秒为单位 106 | +(NSString*)getDurationStartTime:(NSString*)startTime 107 | endTime:(NSString*)endTime; 108 | 109 | //获取两个时间戳的差值,所有值以毫秒为单位 110 | +(NSString*)getHoweSecondsDurationStartTime:(NSString*)startTime 111 | endTime:(NSString*)endTime; 112 | 113 | //获取当前系统时间戳,客户端可能会修改,需要结合差值做校对最后的值 114 | +(NSString*) getCurrentSystemTimeStamp; 115 | 116 | //获取当前网络时间时间戳 117 | + (NSString *)getCurrentInternetDateTimeStamp; 118 | 119 | +(NSString*) getTimeStamp; 120 | 121 | // 获取当前设备可用内存(单位:MB) 122 | + (double)getAvailableMemory; 123 | 124 | // 获取当前任务所占用的内存(单位:MB) 125 | + (double)getUsedMemory; 126 | 127 | +(NSString*) getMemoryUsePercent; 128 | 129 | +(float) getCpuUsage; 130 | 131 | +(int) getCpuUsagePercent; 132 | 133 | // 获取当前设备空闲的存储空间(单位:MB) 134 | + (double)getDeviceFreeSpace; 135 | 136 | // 获取当前设备总的存储空间(单位:MB) 137 | + (double)getDeviceTotalSize; 138 | 139 | //获取当前的时间(单位:毫秒) 140 | + (long long)getDeviceCurrentTime; 141 | 142 | + (void)deletAllFileInFolder:(NSString*)folderPath; 143 | 144 | + (void)deletAllFile:(NSString*)folderPath; 145 | 146 | +(UIInterfaceOrientation) getCurrentScreenOrientation; 147 | 148 | //照片获取本地路径转换 149 | + (NSString *)getImagePath:(UIImage *)image url:(NSString*)url folderPath:(NSString*)folderPath; 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/JSONAPI.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSONAPI.h 3 | // 4 | // @version 1.2 5 | // @author Marin Todorov (http://www.underplot.com) and contributors 6 | // 7 | 8 | // Copyright (c) 2012-2015 Marin Todorov, Underplot ltd. 9 | // This code is distributed under the terms and conditions of the MIT license. 10 | // 11 | // 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: 12 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | // 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. 14 | // 15 | 16 | 17 | #import 18 | #import "JSONHTTPClient.h" 19 | 20 | ///////////////////////////////////////////////////////////////////////////////////////////// 21 | 22 | /** 23 | * @discussion Class for working with JSON APIs. It builds upon the JSONHTTPClient class 24 | * and facilitates making requests to the same web host. Also features helper 25 | * method for making calls to a JSON RPC service 26 | */ 27 | @interface JSONAPI : NSObject 28 | 29 | ///////////////////////////////////////////////////////////////////////////////////////////// 30 | 31 | /** @name Configuring the API */ 32 | /** 33 | * Sets the API url 34 | * @param base the API url as a string 35 | */ 36 | +(void)setAPIBaseURLWithString:(NSString*)base; 37 | 38 | /** 39 | * Sets the default content type for the requests/responses 40 | * @param ctype The content-type as a string. Some possible types, 41 | * depending on the service: application/json, text/json, x-application/javascript, etc. 42 | */ 43 | +(void)setContentType:(NSString*)ctype; 44 | 45 | ///////////////////////////////////////////////////////////////////////////////////////////// 46 | 47 | /** @name Making GET API requests */ 48 | /** 49 | * Makes an asynchronous GET request to the API 50 | * @param path the URL path to add to the base API URL for this HTTP call 51 | * @param params the variables to pass to the API 52 | * @param completeBlock a JSONObjectBlock block to execute upon completion 53 | */ 54 | +(void)getWithPath:(NSString*)path andParams:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock; 55 | 56 | ///////////////////////////////////////////////////////////////////////////////////////////// 57 | 58 | /** @name Making POST API requests */ 59 | /** 60 | * Makes a POST request to the API 61 | * @param path the URL path to add to the base API URL for this HTTP call 62 | * @param params the variables to pass to the API 63 | * @param completeBlock a JSONObjectBlock block to execute upon completion 64 | */ 65 | +(void)postWithPath:(NSString*)path andParams:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock; 66 | 67 | ///////////////////////////////////////////////////////////////////////////////////////////// 68 | 69 | /** @name JSON RPC methods */ 70 | /** 71 | * Makes an asynchronous JSON RPC request to the API. Read more: http://www.jsonrpc.org 72 | * @param method the HTTP method name; GET or POST only 73 | * @param args the list of arguments to pass to the API 74 | * @param completeBlock JSONObjectBlock to execute upon completion 75 | */ 76 | +(void)rpcWithMethodName:(NSString*)method andArguments:(NSArray*)args completion:(JSONObjectBlock)completeBlock; 77 | 78 | /** @name JSON RPC (2.0) request method */ 79 | /** 80 | * Makes an asynchronous JSON RPC 2.0 request to the API. Read more: http://www.jsonrpc.org 81 | * @param method the HTTP method name; GET or POST only 82 | * @param params the params to pass to the API - an NSArray or an NSDictionary, 83 | * depending whether you're using named or unnamed parameters 84 | * @param completeBlock JSONObjectBlock to execute upon completion 85 | */ 86 | +(void)rpc2WithMethodName:(NSString*)method andParams:(id)params completion:(JSONObjectBlock)completeBlock; 87 | 88 | ///////////////////////////////////////////////////////////////////////////////////////////// 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/JSONKeyMapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSONKeyMapper.h 3 | // 4 | // @version 1.2 5 | // @author Marin Todorov (http://www.underplot.com) and contributors 6 | // 7 | 8 | // Copyright (c) 2012-2015 Marin Todorov, Underplot ltd. 9 | // This code is distributed under the terms and conditions of the MIT license. 10 | // 11 | // 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: 12 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | // 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. 14 | // 15 | 16 | 17 | #import 18 | 19 | typedef NSString* (^JSONModelKeyMapBlock)(NSString* keyName); 20 | 21 | /** 22 | * **You won't need to create or store instances of this class yourself.** If you want your model 23 | * to have different property names than the JSON feed keys, look below on how to 24 | * make your model use a key mapper. 25 | * 26 | * For example if you consume JSON from twitter 27 | * you get back underscore_case style key names. For example: 28 | * 29 | *
"profile_sidebar_border_color": "0094C2",
 30 |  * "profile_background_tile": false,
31 | * 32 | * To comply with Obj-C accepted camelCase property naming for your classes, 33 | * you need to provide mapping between JSON keys and ObjC property names. 34 | * 35 | * In your model overwrite the +(JSONKeyMapper*)keyMapper method and provide a JSONKeyMapper 36 | * instance to convert the key names for your model. 37 | * 38 | * If you need custom mapping it's as easy as: 39 | *
 40 |  * +(JSONKeyMapper*)keyMapper {
 41 |  *   return [[JSONKeyMapper alloc] initWithDictionary:@{@"crazy_JSON_name":@"myCamelCaseName"}];
 42 |  * }
 43 |  * 
44 | * In case you want to handle underscore_case, **use the predefined key mapper**, like so: 45 | *
 46 |  * +(JSONKeyMapper*)keyMapper {
 47 |  *   return [JSONKeyMapper mapperFromUnderscoreCaseToCamelCase];
 48 |  * }
 49 |  * 
50 | */ 51 | @interface JSONKeyMapper : NSObject 52 | 53 | /** @name Name converters */ 54 | /** Block, which takes in a JSON key and converts it to the corresponding property name */ 55 | @property (readonly, nonatomic) JSONModelKeyMapBlock JSONToModelKeyBlock; 56 | 57 | /** Block, which takes in a property name and converts it to the corresponding JSON key name */ 58 | @property (readonly, nonatomic) JSONModelKeyMapBlock modelToJSONKeyBlock; 59 | 60 | /** Combined converter method 61 | * @param value the source name 62 | * @param importing YES invokes JSONToModelKeyBlock, NO - modelToJSONKeyBlock 63 | * @return JSONKeyMapper instance 64 | */ 65 | -(NSString*)convertValue:(NSString*)value isImportingToModel:(BOOL)importing; 66 | 67 | /** @name Creating a key mapper */ 68 | 69 | /** 70 | * Creates a JSONKeyMapper instance, based on the two blocks you provide this initializer. 71 | * The two parameters take in a JSONModelKeyMapBlock block: 72 | *
NSString* (^JSONModelKeyMapBlock)(NSString* keyName)
73 | * The block takes in a string and returns the transformed (if at all) string. 74 | * @param toModel transforms JSON key name to your model property name 75 | * @param toJSON transforms your model property name to a JSON key 76 | */ 77 | -(instancetype)initWithJSONToModelBlock:(JSONModelKeyMapBlock)toModel 78 | modelToJSONBlock:(JSONModelKeyMapBlock)toJSON; 79 | 80 | /** 81 | * Creates a JSONKeyMapper instance, based on the mapping you provide 82 | * in the map parameter. Use the JSON key names as keys, your JSONModel 83 | * property names as values. 84 | * @param map map dictionary, in the format:
@{@"crazy_JSON_name":@"myCamelCaseName"}
85 | * @return JSONKeyMapper instance 86 | */ 87 | -(instancetype)initWithDictionary:(NSDictionary*)map; 88 | 89 | /** 90 | * Creates a JSONKeyMapper, which converts underscore_case to camelCase and vice versa. 91 | */ 92 | +(instancetype)mapperFromUnderscoreCaseToCamelCase; 93 | 94 | +(instancetype)mapperFromUpperCaseToLowerCase; 95 | 96 | /** 97 | * Creates a JSONKeyMapper based on a built-in JSONKeyMapper, with specific exceptions. 98 | * Use the original JSON key names as keys, and your JSONModel property names as values. 99 | */ 100 | + (instancetype)mapper:(JSONKeyMapper *)baseKeyMapper withExceptions:(NSDictionary *)exceptions; 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/JSONModel+networking.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSONModel+networking.h 3 | // 4 | // @version 1.2 5 | // @author Marin Todorov (http://www.underplot.com) and contributors 6 | // 7 | 8 | // Copyright (c) 2012-2015 Marin Todorov, Underplot ltd. 9 | // This code is distributed under the terms and conditions of the MIT license. 10 | // 11 | // 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: 12 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | // 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. 14 | // 15 | 16 | 17 | #import "JSONModel.h" 18 | #import "JSONHTTPClient.h" 19 | 20 | typedef void (^JSONModelBlock)(id model, JSONModelError* err); 21 | 22 | /** 23 | * The JSONModel(networking) class category adds networking to JSONModel. 24 | * It adds initFromURLWithString: initializer, which makes a GET http request 25 | * to the URL given and initializes the model with the returned JSON. 26 | * Use #import "JSONModel+networking.h" to import networking capabilities. 27 | */ 28 | @interface JSONModel(Networking) 29 | 30 | @property (assign, nonatomic) BOOL isLoading; 31 | /** @name Asynchronously create a model over the network */ 32 | /** 33 | * Asynchronously create a model over the network. Create a new model instance and initialize it with the JSON fetched from the given URL 34 | * @param urlString the absolute URL address of the JSON feed as a string 35 | * @param completeBlock JSONModelBlock executed upon completion. The JSONModelBlock type is defined as: void (^JSONModelBlock)(JSONModel* model, JSONModelError* e); the first parameter is the initialized model or nil, 36 | * and second parameter holds the model initialization error, if any 37 | */ 38 | -(instancetype)initFromURLWithString:(NSString *)urlString completion:(JSONModelBlock)completeBlock; 39 | 40 | /** 41 | * Asynchronously gets the contents of a URL and constructs a JSONModel object from the response. 42 | * The constructed JSONModel object passed as the first parameter to the completion block will be of the same 43 | * class as the receiver. So call this method on yourJSONModel sub-class rather than directly on JSONModel. 44 | * @param urlString The absolute URL of the JSON resource, as a string 45 | * @param completeBlock The block to be called upon completion. 46 | * JSONModelBlock type is defined as: void (^JSONModelBlock)(JSONModel* model, JSONModelError* err); 47 | * The first parameter is the initialized model (of the same JSONModel sub-class as the receiver) or nil if there was an error; 48 | * The second parameter is the initialization error, if any. 49 | */ 50 | + (void)getModelFromURLWithString:(NSString*)urlString completion:(JSONModelBlock)completeBlock; 51 | 52 | /** 53 | * Asynchronously posts a JSONModel object (as JSON) to a URL and constructs a JSONModel object from the response. 54 | * The constructed JSONModel object passed as the first parameter to the completion block will be of the same 55 | * class as the receiver. So call this method on yourJSONModel sub-class rather than directly on JSONModel. 56 | * @param post A JSONModel object that will be converted to JSON and sent as the POST data to the HTTP request. 57 | * @param urlString The absolute URL of the JSON resource, as a string 58 | * @param completeBlock The block to be called upon completion. 59 | * JSONModelBlock type is defined as: void (^JSONModelBlock)(JSONModel* model, JSONModelError* err); 60 | * The first parameter is the initialized model (of the same JSONModel sub-class as the receiver) or nil if there was an error; 61 | * The second parameter is the initialization error, if any. 62 | */ 63 | + (void)postModel:(JSONModel*)post toURLWithString:(NSString*)urlString completion:(JSONModelBlock)completeBlock; 64 | 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/JSONModelArray.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSONModelArray.h 3 | // 4 | // @version 0.8.0 5 | // @author Marin Todorov (http://www.underplot.com) and contributors 6 | // 7 | 8 | // Copyright (c) 2012-2015 Marin Todorov, Underplot ltd. 9 | // This code is distributed under the terms and conditions of the MIT license. 10 | // 11 | // 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: 12 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | // 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. 14 | // 15 | 16 | 17 | #import 18 | 19 | /** 20 | * **Don't make instances of JSONModelArray yourself, except you know what you are doing.** 21 | * 22 | * You get automatically JSONModelArray instances, when you declare a convert on demand property, like so: 23 | * 24 | * @property (strong, nonatomic) NSArray<JSONModel, ConvertOnDemand>* list; 25 | * 26 | * The class stores its contents as they come from JSON, and upon the first request 27 | * of each of the objects stored in the array, it'll be converted to the target model class. 28 | * Thus saving time upon the very first model creation. 29 | */ 30 | @interface JSONModelArray : NSObject 31 | 32 | /** 33 | * Don't make instances of JSONModelArray yourself, except you know what you are doing. 34 | * 35 | * @param array an array of NSDictionary objects 36 | * @param cls the JSONModel sub-class you'd like the NSDictionaries to be converted to on demand 37 | */ 38 | - (id)initWithArray:(NSArray *)array modelClass:(Class)cls; 39 | 40 | - (id)objectAtIndex:(NSUInteger)index; 41 | - (id)objectAtIndexedSubscript:(NSUInteger)index; 42 | - (void)forwardInvocation:(NSInvocation *)anInvocation; 43 | - (NSUInteger)count; 44 | - (id)firstObject; 45 | - (id)lastObject; 46 | 47 | /** 48 | * Looks up the array's contents and tries to find a JSONModel object 49 | * with matching index property value to the indexValue param. 50 | * 51 | * Will return nil if no matching model is found. Will return nil if there's no index property 52 | * defined on the models found in the array (will sample the first object, assuming the array 53 | * contains homogeneous collection of objects) 54 | * 55 | * @param indexValue the id value to search for 56 | * @return the found model or nil 57 | */ 58 | - (id)modelWithIndexValue:(id)indexValue; 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/JSONModelClassProperty.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSONModelClassProperty.h 3 | // 4 | // @version 1.2 5 | // @author Marin Todorov (http://www.underplot.com) and contributors 6 | // 7 | 8 | // Copyright (c) 2012-2015 Marin Todorov, Underplot ltd. 9 | // This code is distributed under the terms and conditions of the MIT license. 10 | // 11 | // 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: 12 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | // 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. 14 | // 15 | 16 | 17 | #import 18 | 19 | enum kCustomizationTypes { 20 | kNotInspected = 0, 21 | kCustom, 22 | kNo 23 | }; 24 | 25 | typedef enum kCustomizationTypes PropertyGetterType; 26 | 27 | /** 28 | * **You do not need to instantiate this class yourself.** This class is used internally by JSONModel 29 | * to inspect the declared properties of your model class. 30 | * 31 | * Class to contain the information, representing a class property 32 | * It features the property's name, type, whether it's a required property, 33 | * and (optionally) the class protocol 34 | */ 35 | @interface JSONModelClassProperty : NSObject 36 | 37 | /** The name of the declared property (not the ivar name) */ 38 | @property (copy, nonatomic) NSString* name; 39 | 40 | /** A property class type */ 41 | @property (assign, nonatomic) Class type; 42 | 43 | /** Struct name if a struct */ 44 | @property (strong, nonatomic) NSString* structName; 45 | 46 | /** The name of the protocol the property conforms to (or nil) */ 47 | @property (copy, nonatomic) NSString* protocol; 48 | 49 | /** If YES, it can be missing in the input data, and the input would be still valid */ 50 | @property (assign, nonatomic) BOOL isOptional; 51 | 52 | /** If YES - don't call any transformers on this property's value */ 53 | @property (assign, nonatomic) BOOL isStandardJSONType; 54 | 55 | /** If YES - create a mutable object for the value of the property */ 56 | @property (assign, nonatomic) BOOL isMutable; 57 | 58 | /** If YES - create models on demand for the array members */ 59 | @property (assign, nonatomic) BOOL convertsOnDemand; 60 | 61 | /** If YES - the value of this property determines equality to other models */ 62 | @property (assign, nonatomic) BOOL isIndex; 63 | 64 | /** The status of property getter introspection in a model */ 65 | @property (assign, nonatomic) PropertyGetterType getterType; 66 | 67 | /** a custom getter for this property, found in the owning model */ 68 | @property (assign, nonatomic) SEL customGetter; 69 | 70 | /** custom setters for this property, found in the owning model */ 71 | @property (strong, nonatomic) NSMutableDictionary *customSetters; 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/JSONModelError.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSONModelError.h 3 | // 4 | // @version 1.2 5 | // @author Marin Todorov (http://www.underplot.com) and contributors 6 | // 7 | 8 | // Copyright (c) 2012-2015 Marin Todorov, Underplot ltd. 9 | // This code is distributed under the terms and conditions of the MIT license. 10 | // 11 | // 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: 12 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | // 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. 14 | // 15 | 16 | 17 | #import 18 | 19 | ///////////////////////////////////////////////////////////////////////////////////////////// 20 | typedef NS_ENUM(int, kJSONModelErrorTypes) 21 | { 22 | kJSONModelErrorInvalidData = 1, 23 | kJSONModelErrorBadResponse = 2, 24 | kJSONModelErrorBadJSON = 3, 25 | kJSONModelErrorModelIsInvalid = 4, 26 | kJSONModelErrorNilInput = 5 27 | }; 28 | 29 | ///////////////////////////////////////////////////////////////////////////////////////////// 30 | /** The domain name used for the JSONModelError instances */ 31 | extern NSString* const JSONModelErrorDomain; 32 | 33 | /** 34 | * If the model JSON input misses keys that are required, check the 35 | * userInfo dictionary of the JSONModelError instance you get back - 36 | * under the kJSONModelMissingKeys key you will find a list of the 37 | * names of the missing keys. 38 | */ 39 | extern NSString* const kJSONModelMissingKeys; 40 | 41 | /** 42 | * If JSON input has a different type than expected by the model, check the 43 | * userInfo dictionary of the JSONModelError instance you get back - 44 | * under the kJSONModelTypeMismatch key you will find a description 45 | * of the mismatched types. 46 | */ 47 | extern NSString* const kJSONModelTypeMismatch; 48 | 49 | /** 50 | * If an error occurs in a nested model, check the userInfo dictionary of 51 | * the JSONModelError instance you get back - under the kJSONModelKeyPath 52 | * key you will find key-path at which the error occurred. 53 | */ 54 | extern NSString* const kJSONModelKeyPath; 55 | 56 | ///////////////////////////////////////////////////////////////////////////////////////////// 57 | /** 58 | * Custom NSError subclass with shortcut methods for creating 59 | * the common JSONModel errors 60 | */ 61 | @interface JSONModelError : NSError 62 | 63 | @property (strong, nonatomic) NSHTTPURLResponse* httpResponse; 64 | 65 | @property (strong, nonatomic) NSData* responseData; 66 | 67 | /** 68 | * Creates a JSONModelError instance with code kJSONModelErrorInvalidData = 1 69 | */ 70 | +(id)errorInvalidDataWithMessage:(NSString*)message; 71 | 72 | /** 73 | * Creates a JSONModelError instance with code kJSONModelErrorInvalidData = 1 74 | * @param keys a set of field names that were required, but not found in the input 75 | */ 76 | +(id)errorInvalidDataWithMissingKeys:(NSSet*)keys; 77 | 78 | /** 79 | * Creates a JSONModelError instance with code kJSONModelErrorInvalidData = 1 80 | * @param mismatchDescription description of the type mismatch that was encountered. 81 | */ 82 | +(id)errorInvalidDataWithTypeMismatch:(NSString*)mismatchDescription; 83 | 84 | /** 85 | * Creates a JSONModelError instance with code kJSONModelErrorBadResponse = 2 86 | */ 87 | +(id)errorBadResponse; 88 | 89 | /** 90 | * Creates a JSONModelError instance with code kJSONModelErrorBadJSON = 3 91 | */ 92 | +(id)errorBadJSON; 93 | 94 | /** 95 | * Creates a JSONModelError instance with code kJSONModelErrorModelIsInvalid = 4 96 | */ 97 | +(id)errorModelIsInvalid; 98 | 99 | /** 100 | * Creates a JSONModelError instance with code kJSONModelErrorNilInput = 5 101 | */ 102 | +(id)errorInputIsNil; 103 | 104 | /** 105 | * Creates a new JSONModelError with the same values plus information about the key-path of the error. 106 | * Properties in the new error object are the same as those from the receiver, 107 | * except that a new key kJSONModelKeyPath is added to the userInfo dictionary. 108 | * This key contains the component string parameter. If the key is already present 109 | * then the new error object has the component string prepended to the existing value. 110 | */ 111 | - (instancetype)errorByPrependingKeyPathComponent:(NSString*)component; 112 | 113 | ///////////////////////////////////////////////////////////////////////////////////////////// 114 | @end 115 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/JSONModelLib.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSONModelLib.h 3 | // 4 | // @version 1.2 5 | // @author Marin Todorov (http://www.underplot.com) and contributors 6 | // 7 | 8 | // Copyright (c) 2012-2015 Marin Todorov, Underplot ltd. 9 | // This code is distributed under the terms and conditions of the MIT license. 10 | // 11 | // 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: 12 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | // 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. 14 | // 15 | 16 | 17 | #import 18 | 19 | //JSONModel transformations 20 | #import "JSONValueTransformer.h" 21 | #import "JSONKeyMapper.h" 22 | 23 | //basic JSONModel classes 24 | #import "JSONModelError.h" 25 | #import "JSONModelClassProperty.h" 26 | #import "JSONModel.h" 27 | 28 | //network classes 29 | #import "JSONHTTPClient.h" 30 | #import "JSONModel+networking.h" 31 | #import "JSONAPI.h" 32 | 33 | //models array 34 | #import "NSArray+JSONModel.h" 35 | #import "JSONModelArray.h" 36 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/NSArray+JSONModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+JSONModel.h 3 | // 4 | // @version 1.2 5 | // @author Marin Todorov (http://www.underplot.com) and contributors 6 | // 7 | 8 | // Copyright (c) 2012-2015 Marin Todorov, Underplot ltd. 9 | // This code is distributed under the terms and conditions of the MIT license. 10 | // 11 | // 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: 12 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | // 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. 14 | // 15 | 16 | 17 | 18 | #import 19 | #import "JSONModel.h" 20 | 21 | /** 22 | * Exposes invisible JSONModelArray methods 23 | */ 24 | @interface NSArray(JSONModel) 25 | 26 | /** 27 | * Looks up the array's contents and tries to find a JSONModel object 28 | * with matching index property value to the indexValue param. 29 | * 30 | * Will return nil if no matching model is found. Will return nil if there's no index property 31 | * defined on the models found in the array (will sample the first object, assuming the array 32 | * contains homogeneous collection of objects) 33 | * 34 | * @param indexValue the id value to search for 35 | * @return the found model or nil 36 | * @exception NSException throws exception if you call this method on an instance, which is not actually a JSONModelArray 37 | */ 38 | - (id)modelWithIndexValue:(id)indexValue; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/Reachability.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011, Tony Million. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #import 29 | #import 30 | 31 | 32 | /** 33 | * Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X. 34 | * 35 | * @see http://nshipster.com/ns_enum-ns_options/ 36 | **/ 37 | #ifndef NS_ENUM 38 | #define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type 39 | #endif 40 | 41 | extern NSString *const kReachabilityChangedNotification; 42 | 43 | typedef NS_ENUM(NSInteger, NetworkStatus) { 44 | // Apple NetworkStatus Compatible Names. 45 | NotReachable = 0, 46 | ReachableViaWiFi = 2, 47 | ReachableViaWWAN = 1 48 | }; 49 | 50 | @class Reachability; 51 | 52 | typedef void (^NetworkReachable)(Reachability * reachability); 53 | typedef void (^NetworkUnreachable)(Reachability * reachability); 54 | 55 | 56 | @interface Reachability : NSObject 57 | 58 | @property (nonatomic, copy) NetworkReachable reachableBlock; 59 | @property (nonatomic, copy) NetworkUnreachable unreachableBlock; 60 | 61 | @property (nonatomic, assign) BOOL reachableOnWWAN; 62 | 63 | 64 | +(Reachability*)reachabilityWithHostname:(NSString*)hostname; 65 | // This is identical to the function above, but is here to maintain 66 | //compatibility with Apples original code. (see .m) 67 | +(Reachability*)reachabilityWithHostName:(NSString*)hostname; 68 | +(Reachability*)reachabilityForInternetConnection; 69 | +(Reachability*)reachabilityWithAddress:(void *)hostAddress; 70 | +(Reachability*)reachabilityForLocalWiFi; 71 | 72 | -(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref; 73 | 74 | -(BOOL)startNotifier; 75 | -(void)stopNotifier; 76 | 77 | -(BOOL)isReachable; 78 | -(BOOL)isReachableViaWWAN; 79 | -(BOOL)isReachableViaWiFi; 80 | 81 | // WWAN may be available, but not active until a connection has been established. 82 | // WiFi may require a connection for VPN on Demand. 83 | -(BOOL)isConnectionRequired; // Identical DDG variant. 84 | -(BOOL)connectionRequired; // Apple's routine. 85 | // Dynamic, on demand connection? 86 | -(BOOL)isConnectionOnDemand; 87 | // Is user intervention required? 88 | -(BOOL)isInterventionRequired; 89 | 90 | -(NetworkStatus)currentReachabilityStatus; 91 | -(SCNetworkReachabilityFlags)reachabilityFlags; 92 | -(NSString*)currentReachabilityString; 93 | -(NSString*)currentReachabilityFlags; 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/SDKCommonModule.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDKCommonModule.h 3 | // SDKCommonModule 4 | // 5 | // Created by star.liao on 2017/3/30. 6 | // Copyright © 2017年 com.idreamsky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for SDKCommonModule. 12 | FOUNDATION_EXPORT double SDKCommonModuleVersionNumber; 13 | 14 | //! Project version string for SDKCommonModule. 15 | FOUNDATION_EXPORT const unsigned char SDKCommonModuleVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | //#import 21 | //#import 22 | //#import 23 | //#import 24 | //#import 25 | // 26 | // 27 | ////Reachability 28 | //#import 29 | // 30 | ////AFNetworking-3.1.0 31 | //#import 32 | //#import 33 | //#import 34 | //#import 35 | //#import 36 | //#import 37 | //#import 38 | // 39 | ////UIKit+AFNetworking 40 | //#import 41 | //#import 42 | //#import 43 | //#import 44 | //#import 45 | //#import 46 | //#import 47 | //#import 48 | //#import 49 | //#import 50 | //#import 51 | 52 | //JSONModel 53 | //#import 54 | //#import 55 | //#import 56 | //#import 57 | //#import 58 | //#import 59 | //#import 60 | //#import 61 | //#import 62 | //#import 63 | //#import 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/SDKHttpOperationManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AdsHttpOperationManager.h 3 | // SDKCommonModule 4 | // 5 | // Created by star.liao on 2017/4/1. 6 | // Copyright © 2017年 com.idreamsky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol SDKHttpRequestDelegate 12 | 13 | @optional 14 | 15 | -(void) requestResult:(id) responseObject withUrl:(NSString *)url; 16 | 17 | -(void) requestResult:(id) responseObject withUrl:(NSString *)url withHttpBody:(NSString *)httpBody timedifference:(long long)timedifference; 18 | 19 | -(void) requestResult:(id) responseObject withUrl:(NSString *)url withHttpBody:(NSString *)httpBody; 20 | 21 | 22 | @end 23 | 24 | @interface SDKHttpOperationManager : NSObject 25 | 26 | @property(nonatomic,strong) NSString* requestURL; 27 | @property(nonatomic,weak) id delegate; 28 | @property(nonatomic,strong) NSString* userAgent; 29 | @property(nonatomic,assign) NSTimeInterval timeout; 30 | @property(nonatomic,assign) int retryCount; 31 | @property(nonatomic,strong) NSDictionary* headers; 32 | 33 | + (id)requestWithURL:(NSString *)newURL; 34 | 35 | /** 36 | * get请求 37 | */ 38 | -(void) requestData; 39 | 40 | /** 41 | * post请求 42 | * 43 | * @param bodyStr post字符串 44 | */ 45 | -(void) postStringBody:(NSString *)bodyStr; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/SDKUtilManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDKUtilManager.h 3 | // SDKCommonModule 4 | // 5 | // Created by star.liao on 2017/4/1. 6 | // Copyright © 2017年 com.idreamsky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JSONModel.h" 11 | 12 | @interface SDKUtilManager :JSONModel 13 | 14 | //平台_手机品牌_屏幕尺寸_机型_客户端版本_系统版本_分辨率_网络类型_运营商_imei 15 | @property(nonatomic,assign) int systemPlatform; 16 | @property(nonatomic,strong) NSString* imei;//0.2.1是idfa 17 | @property(nonatomic,strong) NSString* device_brand; // iphone5s 18 | @property(nonatomic,strong) NSString* device_model; // iphone 19 | @property(nonatomic,assign) int screenSize; 20 | @property(nonatomic,strong) NSString* uuid;//0.2.1改为从休闲uuid取值,取不到值用idfv 21 | @property(nonatomic,strong) NSString* systemVersion; 22 | @property(nonatomic,strong) NSString* screenResolution; 23 | @property(nonatomic,assign) int screentOrientation; 24 | @property(nonatomic,strong) NSString* CFBundleIdentifier; 25 | @property(nonatomic,strong) NSString* appVersion; 26 | @property(nonatomic,strong) NSString* userAgent; 27 | @property(nonatomic,strong) NSString* systemVersionNumber; 28 | 29 | +(SDKUtilManager *)sharedManager; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/UIActivityIndicatorView+AFNetworking.h: -------------------------------------------------------------------------------- 1 | // UIActivityIndicatorView+AFNetworking.h 2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import 23 | 24 | #import 25 | 26 | #if TARGET_OS_IOS || TARGET_OS_TV 27 | 28 | #import 29 | 30 | /** 31 | This category adds methods to the UIKit framework's `UIActivityIndicatorView` class. The methods in this category provide support for automatically starting and stopping animation depending on the loading state of a session task. 32 | */ 33 | @interface UIActivityIndicatorView (AFNetworking) 34 | 35 | ///---------------------------------- 36 | /// @name Animating for Session Tasks 37 | ///---------------------------------- 38 | 39 | /** 40 | Binds the animating state to the state of the specified task. 41 | 42 | @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled. 43 | */ 44 | - (void)setAnimatingWithStateOfTask:(nullable NSURLSessionTask *)task; 45 | 46 | @end 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/UIImage+AFNetworking.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+AFNetworking.h 3 | // 4 | // 5 | // Created by Paulo Ferreira on 08/07/15. 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | #if TARGET_OS_IOS || TARGET_OS_TV 26 | 27 | #import 28 | 29 | @interface UIImage (AFNetworking) 30 | 31 | + (UIImage*) safeImageWithData:(NSData*)data; 32 | 33 | @end 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/UIImageView+AFNetworking.h: -------------------------------------------------------------------------------- 1 | // UIImageView+AFNetworking.h 2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import 23 | 24 | #import 25 | 26 | #if TARGET_OS_IOS || TARGET_OS_TV 27 | 28 | #import 29 | 30 | NS_ASSUME_NONNULL_BEGIN 31 | 32 | @class AFImageDownloader; 33 | 34 | /** 35 | This category adds methods to the UIKit framework's `UIImageView` class. The methods in this category provide support for loading remote images asynchronously from a URL. 36 | */ 37 | @interface UIImageView (AFNetworking) 38 | 39 | ///------------------------------------ 40 | /// @name Accessing the Image Downloader 41 | ///------------------------------------ 42 | 43 | /** 44 | Set the shared image downloader used to download images. 45 | 46 | @param imageDownloader The shared image downloader used to download images. 47 | */ 48 | + (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader; 49 | 50 | /** 51 | The shared image downloader used to download images. 52 | */ 53 | + (AFImageDownloader *)sharedImageDownloader; 54 | 55 | ///-------------------- 56 | /// @name Setting Image 57 | ///-------------------- 58 | 59 | /** 60 | Asynchronously downloads an image from the specified URL, and sets it once the request is finished. Any previous image request for the receiver will be cancelled. 61 | 62 | If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. 63 | 64 | By default, URL requests have a `Accept` header field value of "image / *", a cache policy of `NSURLCacheStorageAllowed` and a timeout interval of 30 seconds, and are set not handle cookies. To configure URL requests differently, use `setImageWithURLRequest:placeholderImage:success:failure:` 65 | 66 | @param url The URL used for the image request. 67 | */ 68 | - (void)setImageWithURL:(NSURL *)url; 69 | 70 | /** 71 | Asynchronously downloads an image from the specified URL, and sets it once the request is finished. Any previous image request for the receiver will be cancelled. 72 | 73 | If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. 74 | 75 | By default, URL requests have a `Accept` header field value of "image / *", a cache policy of `NSURLCacheStorageAllowed` and a timeout interval of 30 seconds, and are set not handle cookies. To configure URL requests differently, use `setImageWithURLRequest:placeholderImage:success:failure:` 76 | 77 | @param url The URL used for the image request. 78 | @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the image view will not change its image until the image request finishes. 79 | */ 80 | - (void)setImageWithURL:(NSURL *)url 81 | placeholderImage:(nullable UIImage *)placeholderImage; 82 | 83 | /** 84 | Asynchronously downloads an image from the specified URL request, and sets it once the request is finished. Any previous image request for the receiver will be cancelled. 85 | 86 | If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. 87 | 88 | If a success block is specified, it is the responsibility of the block to set the image of the image view before returning. If no success block is specified, the default behavior of setting the image with `self.image = image` is applied. 89 | 90 | @param urlRequest The URL request used for the image request. 91 | @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the image view will not change its image until the image request finishes. 92 | @param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`. 93 | @param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred. 94 | */ 95 | - (void)setImageWithURLRequest:(NSURLRequest *)urlRequest 96 | placeholderImage:(nullable UIImage *)placeholderImage 97 | success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success 98 | failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure; 99 | 100 | /** 101 | Cancels any executing image operation for the receiver, if one exists. 102 | */ 103 | - (void)cancelImageDownloadTask; 104 | 105 | @end 106 | 107 | NS_ASSUME_NONNULL_END 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/UIKit+AFNetworking.h: -------------------------------------------------------------------------------- 1 | // UIKit+AFNetworking.h 2 | // 3 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) 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 13 | // all 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 21 | // THE SOFTWARE. 22 | 23 | #if TARGET_OS_IOS || TARGET_OS_TV 24 | #import 25 | 26 | #ifndef _UIKIT_AFNETWORKING_ 27 | #define _UIKIT_AFNETWORKING_ 28 | 29 | #if TARGET_OS_IOS 30 | #import "AFAutoPurgingImageCache.h" 31 | #import "AFImageDownloader.h" 32 | #import "AFNetworkActivityIndicatorManager.h" 33 | #import "UIRefreshControl+AFNetworking.h" 34 | #import "UIWebView+AFNetworking.h" 35 | #endif 36 | 37 | #import "UIActivityIndicatorView+AFNetworking.h" 38 | #import "UIButton+AFNetworking.h" 39 | #import "UIImageView+AFNetworking.h" 40 | #import "UIProgressView+AFNetworking.h" 41 | #endif /* _UIKIT_AFNETWORKING_ */ 42 | #endif 43 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/UIProgressView+AFNetworking.h: -------------------------------------------------------------------------------- 1 | // UIProgressView+AFNetworking.h 2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import 23 | 24 | #import 25 | 26 | #if TARGET_OS_IOS || TARGET_OS_TV 27 | 28 | #import 29 | 30 | NS_ASSUME_NONNULL_BEGIN 31 | 32 | 33 | /** 34 | This category adds methods to the UIKit framework's `UIProgressView` class. The methods in this category provide support for binding the progress to the upload and download progress of a session task. 35 | */ 36 | @interface UIProgressView (AFNetworking) 37 | 38 | ///------------------------------------ 39 | /// @name Setting Session Task Progress 40 | ///------------------------------------ 41 | 42 | /** 43 | Binds the progress to the upload progress of the specified session task. 44 | 45 | @param task The session task. 46 | @param animated `YES` if the change should be animated, `NO` if the change should happen immediately. 47 | */ 48 | - (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task 49 | animated:(BOOL)animated; 50 | 51 | /** 52 | Binds the progress to the download progress of the specified session task. 53 | 54 | @param task The session task. 55 | @param animated `YES` if the change should be animated, `NO` if the change should happen immediately. 56 | */ 57 | - (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task 58 | animated:(BOOL)animated; 59 | 60 | @end 61 | 62 | NS_ASSUME_NONNULL_END 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/UIRefreshControl+AFNetworking.h: -------------------------------------------------------------------------------- 1 | // UIRefreshControl+AFNetworking.m 2 | // 3 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) 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 13 | // all 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 21 | // THE SOFTWARE. 22 | 23 | #import 24 | 25 | #import 26 | 27 | #if TARGET_OS_IOS 28 | 29 | #import 30 | 31 | NS_ASSUME_NONNULL_BEGIN 32 | 33 | /** 34 | This category adds methods to the UIKit framework's `UIRefreshControl` class. The methods in this category provide support for automatically beginning and ending refreshing depending on the loading state of a session task. 35 | */ 36 | @interface UIRefreshControl (AFNetworking) 37 | 38 | ///----------------------------------- 39 | /// @name Refreshing for Session Tasks 40 | ///----------------------------------- 41 | 42 | /** 43 | Binds the refreshing state to the state of the specified task. 44 | 45 | @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled. 46 | */ 47 | - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task; 48 | 49 | @end 50 | 51 | NS_ASSUME_NONNULL_END 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Headers/UIWebView+AFNetworking.h: -------------------------------------------------------------------------------- 1 | // UIWebView+AFNetworking.h 2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import 23 | 24 | #import 25 | 26 | #if TARGET_OS_IOS 27 | 28 | #import 29 | 30 | NS_ASSUME_NONNULL_BEGIN 31 | 32 | @class AFHTTPSessionManager; 33 | 34 | /** 35 | This category adds methods to the UIKit framework's `UIWebView` class. The methods in this category provide increased control over the request cycle, including progress monitoring and success / failure handling. 36 | 37 | @discussion When using these category methods, make sure to assign `delegate` for the web view, which implements `–webView:shouldStartLoadWithRequest:navigationType:` appropriately. This allows for tapped links to be loaded through AFNetworking, and can ensure that `canGoBack` & `canGoForward` update their values correctly. 38 | */ 39 | @interface UIWebView (AFNetworking) 40 | 41 | /** 42 | The session manager used to download all requests. 43 | */ 44 | @property (nonatomic, strong) AFHTTPSessionManager *sessionManager; 45 | 46 | /** 47 | Asynchronously loads the specified request. 48 | 49 | @param request A URL request identifying the location of the content to load. This must not be `nil`. 50 | @param progress A progress object monitoring the current download progress. 51 | @param success A block object to be executed when the request finishes loading successfully. This block returns the HTML string to be loaded by the web view, and takes two arguments: the response, and the response string. 52 | @param failure A block object to be executed when the data task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred. 53 | */ 54 | - (void)loadRequest:(NSURLRequest *)request 55 | progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress 56 | success:(nullable NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success 57 | failure:(nullable void (^)(NSError *error))failure; 58 | 59 | /** 60 | Asynchronously loads the data associated with a particular request with a specified MIME type and text encoding. 61 | 62 | @param request A URL request identifying the location of the content to load. This must not be `nil`. 63 | @param MIMEType The MIME type of the content. Defaults to the content type of the response if not specified. 64 | @param textEncodingName The IANA encoding name, as in `utf-8` or `utf-16`. Defaults to the response text encoding if not specified. 65 | @param progress A progress object monitoring the current download progress. 66 | @param success A block object to be executed when the request finishes loading successfully. This block returns the data to be loaded by the web view and takes two arguments: the response, and the downloaded data. 67 | @param failure A block object to be executed when the data task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred. 68 | */ 69 | - (void)loadRequest:(NSURLRequest *)request 70 | MIMEType:(nullable NSString *)MIMEType 71 | textEncodingName:(nullable NSString *)textEncodingName 72 | progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress 73 | success:(nullable NSData * (^)(NSHTTPURLResponse *response, NSData *data))success 74 | failure:(nullable void (^)(NSError *error))failure; 75 | 76 | @end 77 | 78 | NS_ASSUME_NONNULL_END 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Info.plist -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module SDKCommonModule { 2 | umbrella header "SDKCommonModule.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/SDKCommonModule: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/insert_sdks/Frameworks/SDKCommonModule.framework/SDKCommonModule -------------------------------------------------------------------------------- /re-sign-ipa/insert_sdks/MobGiAdsToolModuleBundle.bundle/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %page_title% 6 | 7 | 15 | 16 | 17 | 18 |
%error_content%
19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /re-sign-ipa/yololib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/12star9/Python-Tools/dd5f1564670240f4b053355418669b274028e1a7/re-sign-ipa/yololib -------------------------------------------------------------------------------- /sdk_thinning/SDK_Thinning.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | 3 | import sys 4 | import os 5 | import subprocess 6 | import time 7 | 8 | 9 | 10 | 11 | 12 | def init_a_files(): 13 | specify_str = '.a' 14 | sdk_path = u'/Users/star.liao/Desktop/三轮测试游戏工程/TempleRun20425/TR2_SDKList/AdS_SDK/AggregationAdThirdSDKs' 15 | # 搜索指定目录 16 | results = [] 17 | folders = [sdk_path] 18 | 19 | for folder in folders: 20 | # 把目录下所有文件夹存入待遍历的folders 21 | folders += [os.path.join(folder, x) for x in os.listdir(folder) \ 22 | if os.path.isdir(os.path.join(folder, x))] 23 | 24 | # 把所有满足条件的文件的相对地址存入结果results 25 | for x in os.listdir(folder): 26 | if os.path.isfile(os.path.join(folder, x)) and specify_str in x: 27 | sdk_path = os.path.join(folder, x); 28 | if '.framework' in sdk_path: 29 | continue; 30 | results.append(sdk_path); 31 | pass 32 | 33 | return results; 34 | 35 | def init_framework_files(): 36 | specify_str = '.framework' 37 | sdk_path = u'/Users/star.liao/Desktop/三轮测试游戏工程/TempleRun20425/TR2_SDKList/AdS_SDK/AggregationAdThirdSDKs' 38 | # 搜索指定目录 39 | results = [] 40 | folders = [sdk_path] 41 | 42 | for folder in folders: 43 | # 把目录下所有文件夹存入待遍历的folders 44 | folders += [os.path.join(folder, x) for x in os.listdir(folder) \ 45 | if os.path.isdir(os.path.join(folder, x))] 46 | 47 | # 把所有满足条件的文件的相对地址存入结果results 48 | if specify_str in folder: 49 | framework_result= os.path.split(folder); 50 | framework_name= framework_result[1]; 51 | 52 | framework_name_len=len(framework_name); 53 | total_len=framework_name_len-len(specify_str); 54 | result=framework_name[0:total_len]; 55 | framework_name_temp=result; 56 | 57 | if len(result) != 0: 58 | 59 | 60 | for x in os.listdir(folder): 61 | 62 | if x in framework_name_temp: 63 | sdk_path = os.path.join(folder, x); 64 | results.append(sdk_path); 65 | pass; 66 | 67 | return results; 68 | 69 | 70 | 71 | def get_sdk_infos(sdk_path): 72 | cmd = "lipo -info %s" % sdk_path 73 | cmpsplit=cmd.split() 74 | output = subprocess.check_output(cmpsplit) 75 | result=set(output.split()) 76 | architectures=[]; 77 | thin_sdks=[]; 78 | for d in result: 79 | if('armv7' in d or 'armv7s' in d or 'arm64' in d or 'x86_64' in d or 'i386' in d): 80 | architectures.append(d); 81 | output_path = create_arch_framework(sdk_path, d); 82 | if ('armv7' in d or 'armv7s' in d or 'arm64' in d): 83 | 84 | thin_sdks.append(output_path); 85 | 86 | 87 | # create sdk file 88 | 89 | # os.remove(sdk_path); 90 | str = ' '.join(thin_sdks) 91 | created_file_path=sdk_path 92 | cmd = u"lipo -create %s -output %s" % (str, created_file_path) 93 | cmpsplit = cmd.split() 94 | try: 95 | output = subprocess.check_output(cmpsplit) 96 | except subprocess.CalledProcessError, e: 97 | print '%s error:%s!' % (cmd, e) 98 | 99 | # delete 100 | time.sleep(2) 101 | for file_temp in thin_sdks: 102 | if(os.path.exists(file_temp)): 103 | # os.remove(file_temp) 104 | pass 105 | 106 | 107 | 108 | pass 109 | 110 | def get_file_path(sdk_path,rename_name): 111 | root_path = os.path.dirname(sdk_path); 112 | output_sdk_path = '' 113 | if (os.path.isfile(sdk_path)): 114 | array_result= sdk_path.split('/'); 115 | framework_path= array_result[len(array_result)-2]; 116 | framework_sdk_path=array_result[len(array_result)-1]; 117 | if '.a' in framework_sdk_path: 118 | 119 | # 是.a文件 120 | temp_sdk_path = os.path.split(sdk_path) 121 | file_name = temp_sdk_path[1]; 122 | file_name_ext = file_name.split('.'); 123 | file_name = file_name_ext[0] + '_%s' % (rename_name); 124 | new_file_name = '%s/%s.%s' % (root_path, file_name, file_name_ext[1]); 125 | output_sdk_path = new_file_name; 126 | 127 | else: 128 | # framework_root_path=os.path.abspath(os.path.dirname(sdk_path) + os.path.sep + "..") 129 | framework_root_path = os.path.dirname(sdk_path); 130 | output_sdk_path=os.path.join(framework_root_path,'%s_%s' %(framework_sdk_path,rename_name)); 131 | # 是.framework文件 132 | 133 | pass 134 | return output_sdk_path; 135 | 136 | 137 | def create_arch_framework(sdk_path,arch): 138 | # lipo / Users / star.liao / Desktop / InterstitialAd_branch_1 139 | # .8 140 | # .0 / SDK / AggregationAdThirdSDKs / Baidu / 4.5 / BaiduMobAdSDK.framework / BaiduMobAdSDK - thin 141 | # armv7s - output / Users / star.liao / Desktop / InterstitialAd_branch_1 142 | # .8 143 | # .0 / SDK / AggregationAdThirdSDKs / Baidu / BaiduMobAdSDK_7s 144 | 145 | output_sdk_path = get_file_path(sdk_path,arch); 146 | 147 | cmd = u"lipo %s -thin %s -output %s" %(sdk_path,arch,output_sdk_path) 148 | cmpsplit = cmd.split() 149 | try: 150 | output = subprocess.check_output(cmpsplit) 151 | except subprocess.CalledProcessError, e: 152 | print '%s error:%s!' %(cmd,e) 153 | 154 | 155 | pass 156 | return output_sdk_path; 157 | 158 | 159 | 160 | def getFileName(path): 161 | ''' 获取指定目录下的所有指定后缀的文件名 ''' 162 | 163 | # print f_list 164 | for i in os.walk(path): 165 | # os.path.splitext():分离文件名与扩展名 166 | if os.path.splitext(i)[1] == '.a': 167 | print i 168 | 169 | if __name__ == '__main__': 170 | paras_len= len(sys.argv) 171 | if paras_len>=1: 172 | source_file_path = sys.argv[1] 173 | print 'source_file_path:',source_file_path 174 | result_file_path = get_sdk_infos(source_file_path); 175 | print 'success!' 176 | pass -------------------------------------------------------------------------------- /uploadIPA_checks/UploadIPA_Checks.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import os 3 | import subprocess 4 | from biplist import * 5 | 6 | 7 | 8 | 9 | 10 | class AppCheckSystem(object): 11 | 12 | def __init__(self,app_path): 13 | self.app_path = app_path 14 | self.machFilePath=os.path.join(self.app_path,'project_test') 15 | 16 | #找到所有的app-icon图片列表 17 | def get_all_img_files(self): 18 | dir=self.app_path 19 | files_ = [] 20 | list = os.listdir(dir) 21 | for i in range(0, len(list)): 22 | path = os.path.join(dir, list[i]) 23 | if os.path.isdir(path): 24 | print '只做一层文件夹层次判断' 25 | continue 26 | if os.path.isfile(path): 27 | if path.endswith('png') or path.endswith('jpg') or path.endswith('jpeg'): 28 | files_.append(path) 29 | return files_ 30 | 31 | #检查Appicon是否满足要求 32 | def check_AppIcon_Requirements(self): 33 | self.checkfile=os.path.join(self.app_path,'Info.plist') 34 | try: 35 | list=readPlist(self.checkfile) 36 | except Exception, e: 37 | print "Not a plist:", e 38 | 39 | supportedPlatform= list['CFBundleSupportedPlatforms'][0] 40 | warning_str_result='' 41 | #先判断图片是否包含完整 42 | check_iphone_completed=False 43 | check_iphone_appicon_list=[] 44 | check_ipad_completed=False 45 | check_ipad_appicon_list=[] 46 | if supportedPlatform=='iPhoneOS': 47 | if 1 in list['UIDeviceFamily']: 48 | print 'iphone' 49 | if list.has_key('CFBundleIcons'): 50 | CFBundleIcons=list['CFBundleIcons'] 51 | if CFBundleIcons.has_key('CFBundlePrimaryIcon'): 52 | CFBundlePrimaryIcon=CFBundleIcons['CFBundlePrimaryIcon'] 53 | if CFBundlePrimaryIcon.has_key('CFBundleIconName'): 54 | CFBundleIconFilesList=CFBundlePrimaryIcon['CFBundleIconFiles'] 55 | check_iphone_appicon_list=CFBundleIconFilesList 56 | if len(CFBundleIconFilesList)>=4: 57 | 58 | check_iphone_completed=True 59 | if 2 in list['UIDeviceFamily']: 60 | print 'ipad' 61 | if list.has_key('CFBundleIcons~ipad'): 62 | CFBundleIcons=list['CFBundleIcons~ipad'] 63 | if CFBundleIcons.has_key('CFBundlePrimaryIcon'): 64 | CFBundlePrimaryIcon=CFBundleIcons['CFBundlePrimaryIcon'] 65 | if CFBundlePrimaryIcon.has_key('CFBundleIconName'): 66 | CFBundleIconFilesList=CFBundlePrimaryIcon['CFBundleIconFiles'] 67 | check_ipad_appicon_list=CFBundleIconFilesList 68 | if len(CFBundleIconFilesList)>=4: 69 | 70 | check_ipad_completed=True 71 | #再来判断包体内部是否有对应的图片,列出所有图片看有没有包含 72 | img_list=self.get_all_img_files() 73 | #iphone 74 | iphone_img_result={} 75 | for iphone_icon in check_iphone_appicon_list: 76 | for img_temp in img_list: 77 | #匹配图片名? 78 | if iphone_icon in img_temp: 79 | iphone_img_result['%s'%(iphone_icon)]=True 80 | break 81 | else: 82 | iphone_img_result['%s'%(iphone_icon)]=False 83 | continue 84 | #ipad 85 | ipad_img_result={} 86 | for ipad_icon in check_ipad_appicon_list: 87 | for img_temp in img_list: 88 | #匹配图片名? 89 | if ipad_icon in img_temp: 90 | ipad_img_result['%s'%(ipad_icon)]=True 91 | break 92 | else: 93 | ipad_img_result['%s'%(ipad_icon)]=False 94 | continue 95 | 96 | 97 | #判断尺寸是否满足要求 98 | 99 | pass 100 | 101 | #检查可执行文件的__TEXT段大小是否满足大小要求 102 | def check_MachO_File(self,ios_version): 103 | process=subprocess.Popen('size %s'%(self.machFilePath),shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.STDOUT) 104 | (stdoutdata, stderrdata) = process.communicate() 105 | print stdoutdata 106 | result=stdoutdata.split('\n') 107 | size_result=0 108 | List_size_result=[] 109 | for temp_result in range(1,len(result)): 110 | result2=result[temp_result].split('\t') 111 | for temp_str in result2: 112 | if 'arm' in temp_str: 113 | size_result+=int(result2[0]) 114 | List_size_result.append(int(result2[0])) 115 | pass 116 | return_result=True 117 | if ios_version>=9: 118 | if (size_result/1024/1024)>500: 119 | return_result=False 120 | pass 121 | pass 122 | elif ios_version>=7 and ios_version<=8: 123 | for temp_size in List_size_result: 124 | if (temp_size/1024/1024)>60: 125 | return_result=False 126 | break 127 | pass 128 | pass 129 | 130 | elif ios_version<7: 131 | if (size_result/1024/1024)>80: 132 | return_result=False 133 | pass 134 | return return_result 135 | pass 136 | 137 | appCheckSystem=AppCheckSystem('./project_test.app') 138 | appCheckSystem.check_AppIcon_Requirements() 139 | # appCheckSystem.check_MachO_File=check_MachO_File(6) 140 | # if check_MachO_File==False: 141 | # print '检查不通过!' 142 | # else: 143 | # print '检查通过' -------------------------------------------------------------------------------- /xcode_build/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Python: 当前文件", 9 | "type": "python", 10 | "request": "launch", 11 | "program": "${file}", 12 | "console": "integratedTerminal" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /xcode_build/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.pythonPath": "/usr/bin/python" 3 | } -------------------------------------------------------------------------------- /xcode_build/app_main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #-*- coding:utf-8 -*- 3 | 4 | import os, sys 5 | try: 6 | from tkinter import * 7 | except ImportError: #Python 2.x 8 | PythonVersion = 2 9 | from Tkinter import * 10 | from tkFont import Font 11 | from ttk import * 12 | #Usage:showinfo/warning/error,askquestion/okcancel/yesno/retrycancel 13 | from tkMessageBox import * 14 | #Usage:f=tkFileDialog.askopenfilename(initialdir='E:/Python') 15 | #import tkFileDialog 16 | #import tkSimpleDialog 17 | else: #Python 3.x 18 | PythonVersion = 3 19 | from tkinter.font import Font 20 | from tkinter.ttk import * 21 | from tkinter.messagebox import * 22 | #import tkinter.filedialog as tkFileDialog 23 | #import tkinter.simpledialog as tkSimpleDialog #askstring() 24 | 25 | class Application_ui(Frame): 26 | #这个类仅实现界面生成功能,具体事件处理代码在子类Application中。 27 | def __init__(self, master=None): 28 | Frame.__init__(self, master) 29 | self.master.title('Form1') 30 | self.master.geometry('687x446') 31 | self.createWidgets() 32 | 33 | def createWidgets(self): 34 | self.top = self.winfo_toplevel() 35 | 36 | self.style = Style() 37 | 38 | self.Combo1List = ['Add items in design or code!',] 39 | self.Combo1 = Combobox(self.top, values=self.Combo1List, font=('宋体',9)) 40 | self.Combo1.place(relx=0.023, rely=0.036, relwidth=0.421, relheight=0.045) 41 | self.Combo1.set(self.Combo1List[0]) 42 | 43 | self.Combo2List = ['Add items in design or code!',] 44 | self.Combo2 = Combobox(self.top, values=self.Combo2List, font=('宋体',9)) 45 | self.Combo2.place(relx=0.012, rely=0.108, relwidth=0.432, relheight=0.045) 46 | self.Combo2.set(self.Combo2List[0]) 47 | 48 | self.List1Var = StringVar(value='List1') 49 | self.List1Font = Font(font=('宋体',9)) 50 | self.List1 = Listbox(self.top, listvariable=self.List1Var, font=self.List1Font) 51 | self.List1.place(relx=0.023, rely=0.197, relwidth=0.432, relheight=0.224) 52 | 53 | self.style.configure('Command1.TButton',font=('宋体',9)) 54 | self.Command1 = Button(self.top, text='Command1', command=self.Command1_Cmd, style='Command1.TButton') 55 | self.Command1.place(relx=0.023, rely=0.484, relwidth=0.409, relheight=0.074) 56 | 57 | self.style.configure('Command2.TButton',font=('宋体',9)) 58 | self.Command2 = Button(self.top, text='Command2', command=self.Command2_Cmd, style='Command2.TButton') 59 | self.Command2.place(relx=0.023, rely=0.61, relwidth=0.421, relheight=0.074) 60 | 61 | self.style.configure('Command3.TButton',font=('宋体',9)) 62 | self.Command3 = Button(self.top, text='Command3', command=self.Command3_Cmd, style='Command3.TButton') 63 | self.Command3.place(relx=0.023, rely=0.717, relwidth=0.421, relheight=0.074) 64 | 65 | self.style.configure('Command4.TButton',font=('宋体',9)) 66 | self.Command4 = Button(self.top, text='Command4', command=self.Command4_Cmd, style='Command4.TButton') 67 | self.Command4.place(relx=0.023, rely=0.825, relwidth=0.421, relheight=0.074) 68 | 69 | self.style.configure('Command5.TButton',font=('宋体',9)) 70 | self.Command5 = Button(self.top, text='Command5', command=self.Command5_Cmd, style='Command5.TButton') 71 | self.Command5.place(relx=0.023, rely=0.915, relwidth=0.421, relheight=0.074) 72 | 73 | 74 | class Application(Application_ui): 75 | #这个类实现具体的事件处理回调函数。界面生成代码在Application_ui中。 76 | def __init__(self, master=None): 77 | Application_ui.__init__(self, master) 78 | 79 | def Command1_Cmd(self, event=None): 80 | #TODO, Please finish the function here! 81 | pass 82 | 83 | def Command2_Cmd(self, event=None): 84 | #TODO, Please finish the function here! 85 | pass 86 | 87 | def Command3_Cmd(self, event=None): 88 | #TODO, Please finish the function here! 89 | pass 90 | 91 | def Command4_Cmd(self, event=None): 92 | #TODO, Please finish the function here! 93 | pass 94 | 95 | def Command5_Cmd(self, event=None): 96 | #TODO, Please finish the function here! 97 | pass 98 | 99 | if __name__ == "__main__": 100 | top = Tk() 101 | Application(top).mainloop() 102 | try: top.destroy() 103 | except: pass 104 | -------------------------------------------------------------------------------- /xcode_build/auto_generate_app_icons.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import os ,threading 3 | from PIL import Image 4 | import subprocess 5 | import json 6 | 7 | class ImgManager(object): 8 | thread_lock = threading.Lock() 9 | @classmethod 10 | def sharedinstance(cls): 11 | with ImgManager.thread_lock: 12 | if not hasattr(ImgManager,"instance"): 13 | ImgManager.instance = ImgManager() 14 | return ImgManager.instance 15 | 16 | # 运行shell命令 17 | def runshellCMD(self,cmd,dsr): 18 | progress = subprocess.Popen(cmd,shell=True) 19 | progress.wait() 20 | result = progress.returncode 21 | if result !=0: 22 | print("%s失败"%(dsr)) 23 | else: 24 | print("%s成功"%(dsr)) 25 | 26 | #创建图片 27 | def createImg(self,model): 28 | path = '%s/project_test/project_test/Assets.xcassets/AppIcon.appiconset/AppStore.png'%(os.getcwd()) 29 | currentPath = "%s/Images/%s"%(os.getcwd(),model.filename) 30 | print(currentPath) 31 | im = Image.open(path,'r') 32 | # w,h=im.size 33 | # print("%s,%s"%(str(w),str(h))) 34 | # 35 | im.thumbnail((float(model.get_wh()),float(model.get_wh()))) 36 | if model.filename.endswith('.png'): 37 | im.save("%s" % (currentPath),"png") 38 | else: 39 | # self.runshellCMD("sudo cp %s %s" % (path, currentPath), "拷贝") 40 | self.addTransparency(im) 41 | im.save("%s" % (currentPath), "jpeg") 42 | # r, g, b, alpha = im.split() 43 | # print("%s"%(str(im.split()[0]))) 44 | 45 | #修改透明度 46 | def addTransparency(img, factor=0.0): 47 | img = img.convert('RGBA') 48 | img_blender = Image.new('RGBA', img.size, (0, 0, 256, 256)) 49 | img = Image.blend(img_blender, img, factor) 50 | return img 51 | 52 | 53 | #解析Contents.json,这个文件每一个Images.xcassets 的AppIcon文件夹都有,直接复用就可以了 54 | def handle_icon_images(self): 55 | 56 | jsonpath = os.getcwd() +"/project_test/project_test/Assets.xcassets/AppIcon.appiconset/Contents.json" 57 | if not os.path.exists(jsonpath): 58 | print("Contents.json path not exite") 59 | return 60 | with open(jsonpath,'r') as f: 61 | jsonstr = f.read() 62 | modle = json.loads(jsonstr) 63 | arrs = modle['images'] 64 | # print(arrs) 65 | icon_models=[] 66 | for obj in arrs: 67 | size=obj["size"] 68 | idiom=obj["idiom"] 69 | filename=obj["filename"] 70 | scale=obj["scale"] 71 | icom =iconImg(size=size,idiom=idiom,filename=filename,scale=scale) 72 | # icon_models.append(icom) 73 | self.createImg(icom) 74 | 75 | 76 | #json 数据里面有效数据的类 77 | class iconImg(object): 78 | def __init__(self,size,idiom,filename,scale): 79 | self.size = size 80 | self.idiom = idiom 81 | self.filename = filename 82 | self.scale = scale 83 | 84 | def show(self): 85 | print("%s,%s,%s,%s"%(self.size,self.idiom,self.filename,self.scale)) 86 | 87 | 88 | def get_wh(self): 89 | return (float(self.size.split('x')[0]))*(float(self.scale.split('x')[0])) 90 | 91 | 92 | if __name__ == '__main__': 93 | ImgManager.sharedinstance().handle_icon_images() -------------------------------------------------------------------------------- /xcode_build/auto_generate_macos_app.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import os 3 | import subprocess 4 | import json 5 | 6 | current_Path=os.getcwd() 7 | commendFilePath=current_Path+"/system_dependency_config.json" 8 | 9 | def system_dependency_write(bool_val): 10 | fout = open(commendFilePath,'w') 11 | js = {} 12 | js['state_val']=bool_val 13 | outStr = json.dumps(js,ensure_ascii = False) 14 | fout.write(outStr.strip().encode('utf-8') + '\n') 15 | fout.close() 16 | 17 | def read_system_dependency(): 18 | if os.path.exists(commendFilePath)==False: 19 | return None 20 | fin = open(commendFilePath,'r') 21 | result=None 22 | for eachLine in fin: 23 | line = eachLine.strip().decode('utf-8') 24 | line = line.strip(',') 25 | js = None 26 | try: 27 | js = json.loads(line) 28 | result=js['state_val'] 29 | break 30 | except Exception, e: 31 | print e 32 | continue 33 | return result 34 | 35 | def clean_up(): 36 | os.system('cd %s'%(current_Path)) 37 | os.system('rm -rf build dist') 38 | # os.system('rm -rf setup.py') 39 | 40 | def generate_main(main_name='gui_main'): 41 | 42 | os.system('cd %s'%(current_Path)) 43 | os.system('pwd') 44 | state_val=read_system_dependency() 45 | if state_val==None or state_val==False: 46 | buildCmd='easy_install -U git+https://github.com/metachris/py2app.git@master' 47 | process = subprocess.Popen(buildCmd, shell=True) 48 | process.wait() 49 | signReturnCode = process.returncode 50 | if signReturnCode == 0: 51 | system_dependency_write(True) 52 | else: 53 | system_dependency_write(False) 54 | pass 55 | process2=subprocess.Popen('py2applet --make-setup %s.py'%(main_name),shell=True) 56 | #这里可能会提示是否覆盖?? 57 | process2.wait() 58 | 59 | 60 | os.system('rm -rf build dist') 61 | process3=subprocess.Popen('python setup.py py2app',shell=True) 62 | process3.wait() 63 | signReturnCode = process3.returncode 64 | if signReturnCode == 0: 65 | target_path=os.path.join(current_Path,"dist/%s"%(main_name)) 66 | print '生成MacOSX桌面程序成功!路径在:%s.app'%(target_path) 67 | os.system('open %s.app'%(target_path)) 68 | pass 69 | else: 70 | 71 | pass 72 | return 73 | 74 | clean_up() 75 | generate_main('gui_main') 76 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/PBXKey.py: -------------------------------------------------------------------------------- 1 | class PBXKey(str): 2 | def __new__(cls, value, parent): 3 | obj = str.__new__(cls, value) 4 | obj._parent = parent 5 | return obj 6 | 7 | def __repr__(self): 8 | comment = self._get_comment() 9 | if comment is not None: 10 | comment = u' /* {0} */'.format(comment) 11 | else: 12 | comment = u'' 13 | 14 | return u'{0}{1}'.format(self.__str__(), comment) 15 | 16 | def get_parent(self): 17 | return self._parent 18 | 19 | def _get_comment(self): 20 | return self.get_parent()._resolve_comment(self) 21 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/PBXList.py: -------------------------------------------------------------------------------- 1 | class PBXList(list): 2 | pass 3 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/PBXObjects.py: -------------------------------------------------------------------------------- 1 | from pbxproj import PBXGenericObject 2 | 3 | 4 | class objects(PBXGenericObject): 5 | def __init__(self, parent=None): 6 | super(objects, self).__init__(parent) 7 | 8 | # sections: dict 9 | # sections get aggregated under the isa type. Each contains a list of tuples (id, obj) with every object defined 10 | self._sections = {} 11 | 12 | def parse(self, object_data): 13 | # iterate over the keys and fill the sections 14 | if isinstance(object_data, dict): 15 | for key, value in list(object_data.items()): 16 | key = self._parse_string(key) 17 | obj_type = key 18 | if 'isa' in value: 19 | obj_type = value['isa'] 20 | 21 | child = self._get_instance(obj_type, value) 22 | child[u'_id'] = key 23 | self[key] = child 24 | 25 | return self 26 | 27 | # safe-guard: delegate to the parent how to deal with non-object values 28 | return super(objects, self).parse(object_data) 29 | 30 | def _print_object(self, indentation_depth=u'', entry_separator=u'\n', object_start=u'\n', 31 | indentation_increment=u'\t'): 32 | # override to change the way the object is printed out 33 | result = u'{\n' 34 | for section in self.get_sections(): 35 | phase = self._sections[section] 36 | phase.sort(key=lambda x: x.get_id()) 37 | result += u'\n/* Begin {0} section */\n'.format(section) 38 | for value in phase: 39 | obj = value._print_object(indentation_depth + u'\t', entry_separator, object_start, 40 | indentation_increment) 41 | result += indentation_depth + u'\t{0} = {1};\n'.format(value.get_id().__repr__(), obj) 42 | result += u'/* End {0} section */\n'.format(section) 43 | result += indentation_depth + u'}' 44 | return result 45 | 46 | def get_keys(self): 47 | """ 48 | :return: all the keys of the object (ids of objects) 49 | """ 50 | keys = [] 51 | for section in self.get_sections(): 52 | phase = self._sections[section] 53 | for obj in phase: 54 | keys += obj.get_id() 55 | keys.sort() 56 | return keys 57 | 58 | def get_sections(self): 59 | sections = list(self._sections.keys()) 60 | sections.sort() 61 | return sections 62 | 63 | def __getitem__(self, key): 64 | for section in self.get_sections(): 65 | phase = self._sections[section] 66 | for obj in phase: 67 | if key == obj.get_id(): 68 | return obj 69 | return None 70 | 71 | def __setitem__(self, key, value): 72 | if value.isa not in self._sections: 73 | self._sections[value.isa] = [] 74 | 75 | self._sections[value.isa].append(value) 76 | value._parent = self 77 | 78 | def __delitem__(self, key): 79 | obj = self[key] 80 | if obj is not None: 81 | phase = self._sections[obj.isa] 82 | phase.remove(obj) 83 | 84 | # remove empty phases 85 | if phase.__len__() == 0: 86 | del self._sections[obj.isa] 87 | 88 | def __contains__(self, item): 89 | return self[item] is not None 90 | 91 | def __len__(self): 92 | return sum([section.__len__() for section in self._sections]) 93 | 94 | def get_objects_in_section(self, *sections): 95 | result = [] 96 | for name in sections: 97 | if name in self._sections: 98 | result.extend(self._sections[name]) 99 | return result 100 | 101 | def get_targets(self, name=None): 102 | """ 103 | Retrieve all/one target objects 104 | :param name: name of the target to search for, None for everything 105 | :return: A list of target objects 106 | """ 107 | targets = [] 108 | for section in self.get_sections(): 109 | if section.endswith(u'Target'): 110 | targets += [value for value in self._sections[section]] 111 | 112 | if name is None: 113 | return targets 114 | 115 | if not isinstance(name, list): 116 | name = [name] 117 | 118 | return [target for target in targets if target.name in name] 119 | 120 | # def get_configurations_on_targets(self, target_name=None): 121 | 122 | def get_configurations_on_targets(self, target_name=None, configuration_name=None): 123 | """ 124 | Retrieves all configuration given a name on the specified target 125 | :param target_name: Searches for a specific target name or a list of target names. If None all targets are used 126 | :param configuration_name: Searches for a specific configuration, if None all configuration of the target 127 | are used 128 | :return: A generator of configurations objects matching the target and configuration given (or all if nothing is 129 | specified) 130 | """ 131 | for target in self.get_targets(target_name): 132 | configuration_list = self[target.buildConfigurationList] 133 | for configuration in configuration_list.buildConfigurations: 134 | if configuration_name is None or self[configuration].name == configuration_name: 135 | yield self[configuration] 136 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/PBXRootObject.py: -------------------------------------------------------------------------------- 1 | from pbxproj import PBXGenericObject 2 | 3 | 4 | class rootObject(PBXGenericObject): 5 | def _resolve_comment(self, key): 6 | return self.get_parent().objects._resolve_comment(key) 7 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/XcodeProject.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import shutil 3 | import datetime 4 | from pbxproj.pbxextensions import * 5 | 6 | 7 | class XcodeProject(PBXGenericObject, ProjectFiles, ProjectFlags, ProjectGroups): 8 | """ 9 | Top level class, handles the project CRUD operations, new, load, save, delete. Also, exposes methods to manipulate 10 | the project's content, add/remove files, add/remove libraries/frameworks, query sections. For more advanced 11 | operations, underlying objects are exposed that can be manipulated using said objects. 12 | """ 13 | 14 | def __init__(self, tree=None, path=None): 15 | super(XcodeProject, self).__init__(parent=None) 16 | 17 | if path is None: 18 | path = os.path.join(os.getcwd(), 'project.pbxproj') 19 | 20 | self._pbxproj_path = os.path.abspath(path) 21 | #.xcodeproj项目根路径 22 | self._source_root = os.path.abspath(os.path.join(os.path.split(path)[0], '..')) 23 | 24 | # initialize the structure using the given tree 25 | self.parse(tree) 26 | 27 | def save(self, path=None): 28 | if path is None: 29 | path = self._pbxproj_path 30 | 31 | f = open(path, 'w') 32 | f.write(self.__repr__()) 33 | f.close() 34 | 35 | def backup(self): 36 | backup_name = "%s_%s.backup" % (self._pbxproj_path, datetime.datetime.now().strftime('%d%m%y-%H%M%S')) 37 | 38 | shutil.copy2(self._pbxproj_path, backup_name) 39 | return backup_name 40 | 41 | def __repr__(self): 42 | return u'// !$*UTF8*$!\n' + super(XcodeProject, self).__repr__() 43 | 44 | def get_ids(self): 45 | return self.objects.get_keys() 46 | 47 | def get_build_phases_by_name(self, phase_name): 48 | return self.objects.get_objects_in_section(phase_name) 49 | 50 | def get_build_files_for_file(self, file_id): 51 | return [build_file for build_file in self.objects.get_objects_in_section(u'PBXBuildFile') 52 | if build_file.fileRef == file_id] 53 | 54 | def get_target_by_name(self, name): 55 | targets = self.objects.get_targets(name) 56 | if targets.__len__() > 0: 57 | return targets[0] 58 | return None 59 | 60 | def get_targets_names(self): 61 | targets= self.objects.get_targets() 62 | result=[] 63 | for target_temp in targets: 64 | result.append(target_temp.name) 65 | return result 66 | 67 | def get_configSet_By_Target(self,target_name): 68 | result=[] 69 | temp_result= self.get_target_by_name(target_name) 70 | targets= self.objects.get_targets() 71 | configSets=[] 72 | for target_temp in targets: 73 | if target_temp.name==target_name: 74 | configuration_list = self.objects[target_temp.buildConfigurationList] 75 | configSets=configuration_list['buildConfigurations'] 76 | break 77 | pass 78 | for configSet_temp in configSets: 79 | temp_Obj=self.objects[configSet_temp] 80 | result.append(temp_Obj.name) 81 | pass 82 | return result 83 | pass 84 | 85 | def get_object(self, object_id): 86 | return self.objects[object_id] 87 | 88 | @classmethod 89 | def load(cls, path): 90 | import openstep_parser as osp 91 | # tree即结构化的.pbxproj数据 92 | tree = osp.OpenStepDecoder.ParseFromFile(open(path, 'r')) 93 | return XcodeProject(tree, path) 94 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/__init__.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2016 Ignacio Calderon aka kronenthaler 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 | 23 | from pbxproj.PBXList import PBXList 24 | from pbxproj.PBXGenericObject import PBXGenericObject 25 | from pbxproj.PBXObjects import objects 26 | from pbxproj.PBXRootObject import rootObject 27 | from pbxproj.XcodeProject import XcodeProject 28 | from pbxproj.pbxsections import * 29 | 30 | __version__ = '2.5.1' 31 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/__main__.py: -------------------------------------------------------------------------------- 1 | """ 2 | usage: 3 | pbxproj [--version] [--help] [ ...] 4 | 5 | options: 6 | -v, --version Shows version of pbxproj running 7 | -h, --help This message 8 | 9 | commands: 10 | show Displays information about the project targets 11 | file Manipulates files on a project 12 | flag Manipulates compilation flags on the project 13 | folder Manipulates folders or groups on a project 14 | 15 | See pbxproj --help, for more information about a specific command. 16 | """ 17 | from pbxproj.pbxcli import * 18 | import pbxproj 19 | from docopt import docopt 20 | 21 | 22 | def main(): 23 | args = docopt(__doc__, options_first=True, version=u'pbxproj version {0}'.format(pbxproj.__version__)) 24 | argv = [args['']] + args[''] 25 | if args[''] == 'file': 26 | import pbxproj.pbxcli.pbxproj_file as pbxproj_file 27 | command_parser(pbxproj_file.execute)(docopt(pbxproj_file.__doc__, argv=argv)) 28 | elif args[''] == 'flag': 29 | import pbxproj.pbxcli.pbxproj_flag as pbxproj_flag 30 | command_parser(pbxproj_flag.execute)(docopt(pbxproj_flag.__doc__, argv=argv)) 31 | elif args[''] == 'folder': 32 | import pbxproj.pbxcli.pbxproj_folder as pbxproj_folder 33 | command_parser(pbxproj_folder.execute)(docopt(pbxproj_folder.__doc__, argv=argv)) 34 | elif args[''] == 'show': 35 | import pbxproj.pbxcli.pbxproj_show as pbxproj_show 36 | command_parser(pbxproj_show.execute, auto_save=False)(docopt(pbxproj_show.__doc__, argv=argv)) 37 | 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxcli/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | from __future__ import print_function 3 | from __future__ import division 4 | from __future__ import absolute_import 5 | from future import standard_library 6 | standard_library.install_aliases() 7 | 8 | 9 | import os 10 | from pbxproj.XcodeProject import XcodeProject 11 | 12 | 13 | def open_project(args): 14 | if os.path.isdir(args[u'']): 15 | args[u''] += u"/project.pbxproj" 16 | 17 | if not os.path.isfile(args[u'']): 18 | raise Exception(u'Project file not found') 19 | 20 | return XcodeProject.load(args[u'']) 21 | 22 | 23 | def backup_project(project, args): 24 | if args[u'--backup']: 25 | return project.backup() 26 | return None 27 | 28 | 29 | def resolve_backup(project, backup_file, args): 30 | # remove backup if everything was ok. 31 | if args[u'--backup'] and backup_file: 32 | os.remove(backup_file) 33 | 34 | 35 | def command_parser(command, auto_save=True): 36 | def parser(args): 37 | try: 38 | project = open_project(args) 39 | backup_file = backup_project(project, args) 40 | print(command(project, args)) 41 | if auto_save: 42 | project.save() 43 | resolve_backup(project, backup_file, args) 44 | except Exception as ex: 45 | print(u"{0}".format(ex)) 46 | exit(1) 47 | return parser 48 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxcli/pbxproj_file.py: -------------------------------------------------------------------------------- 1 | """ 2 | usage: 3 | pbxproj file [options] [--target ...] 4 | [(--weak | -w)] 5 | [(--no-embed | -E)] 6 | [(--sign-on-copy | -s)] 7 | [(--ignore-unknown-types | -i)] 8 | [(--no-create-build-files | -C)] 9 | [(--header-scope | -H )] 10 | pbxproj file [options] (--delete | -D) 11 | 12 | positional arguments: 13 | Project path to the .xcodeproj folder. 14 | Path of the file to add to the project. 15 | 16 | generic options: 17 | -h, --help This message. 18 | --tree Tree to add the file relative to. Available options: , , 19 | SOURCE_ROOT, SDKROOT, DEVELOPER_DIR, BUILT_PRODUCTS_DIR. [default: SOURCE_ROOT] 20 | -t, --target Target name(s) to be modified. If there is no target specified, all targets are 21 | modified. 22 | -b, --backup Creates a backup before start processing the command. 23 | 24 | delete options: 25 | -D, --delete Delete the file. 26 | 27 | add options: 28 | -w, --weak Add the weak flag when libraries or frameworks are added. Linking optional. 29 | -E, --no-embed Do not embed frameworks when added. 30 | -s, --sign-on-copy Sign frameworks when copied/embedded. 31 | -i, --ignore-unknown-types Ignore unknown file types when added. 32 | -C, --no-create-build-files Do not create build file phases when adding a file. 33 | -H, --header-scope Add header file using the given scope. Available options: public or private, project. 34 | [default: project] 35 | """ 36 | from pbxproj.pbxcli import * 37 | from pbxproj.pbxextensions.ProjectFiles import FileOptions 38 | from docopt import docopt 39 | 40 | 41 | def execute(project, args): 42 | # make a decision of what function to call based on the -D flag 43 | if args[u'--delete']: 44 | return _remove(project, args) 45 | else: 46 | return _add(project, args) 47 | 48 | 49 | def _add(project, args): 50 | if u'--header-scope' not in args or args[u'--header-scope'] not in ['public', 'private', 'project']: 51 | header_scope = u'project' 52 | else: 53 | header_scope = args[u'--header-scope'] 54 | 55 | options = FileOptions(create_build_files=not args[u'--no-create-build-files'], 56 | weak=args[u'--weak'], 57 | ignore_unknown_type=args[u'--ignore-unknown-types'], 58 | embed_framework=not args[u'--no-embed'], 59 | code_sign_on_copy=args[u'--sign-on-copy'], 60 | header_scope=header_scope.title()) 61 | build_files = project.add_file(args[u''], tree=args[u'--tree'], force=False, target_name=args[u'--target'], 62 | file_options=options) 63 | # print some information about the build files created. 64 | if build_files is None: 65 | raise Exception(u'No files were added to the project.') 66 | 67 | if not build_files: 68 | return u'File added to the project, no build file sections created.' 69 | 70 | info = {} 71 | for build_file in build_files: 72 | if build_file.isa not in info: 73 | info[build_file.isa] = 0 74 | info[build_file.isa] += 1 75 | 76 | summary = u'File added to the project.' 77 | for k in info: 78 | summary += u'\n{0} {1} sections created.'.format(info[k], k) 79 | return summary 80 | 81 | 82 | def _remove(project, args): 83 | if project.remove_files_by_path(args[u''], tree=args[u'--tree'], target_name=args[u'--target']): 84 | return u'File removed from the project.' 85 | raise Exception(u'An error occurred removing one of the files.') 86 | 87 | 88 | def main(): 89 | command_parser(execute)(docopt(__doc__)) 90 | 91 | 92 | if __name__ == '__main__': 93 | main() 94 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxcli/pbxproj_flag.py: -------------------------------------------------------------------------------- 1 | """ 2 | usage: 3 | pbxproj flag [options] [--target ...] [--] ( )... 4 | pbxproj flag [options] (--delete | -D) [--] ( )... 5 | 6 | positional arguments: 7 | Project path to the .xcodeproj folder. 8 | Flag name to be modified in the project's configuration(s). 9 | Flag value to be modified in the project's configuration(s). 10 | 11 | generic options: 12 | -- Force to read the flag_value's and flag_name's as they are, otherwise they 13 | might be interpreted as an option and detected as such. Use when a 14 | flag_value starts with -, like -ObjC 15 | -h, --help This message. 16 | -t, --target Target name(s) to be modified. If there is no target specified, all targets 17 | are modified. 18 | -b, --backup Creates a backup before start processing the command. 19 | -c, --configuration Configuration name to modify the flags. If no configuration name is 20 | provided, all configurations are affected. 21 | 22 | delete options: 23 | -D, --delete Removes the given flag_value's from the pairing flag_name. 24 | """ 25 | 26 | # Future addition to the command line: 27 | # pbxproj flag [options] (--delete | -D) (--all | -A) [--] ... 28 | 29 | from pbxproj.pbxcli import * 30 | from docopt import docopt 31 | 32 | 33 | def execute(project, args): 34 | # make a decision of what function to call based on the -D flag 35 | if args[u'--delete']: 36 | return _remove(project, args) 37 | else: 38 | return _add(project, args) 39 | 40 | 41 | def _add(project, args): 42 | for (flag_name, flag_value) in zip(args[u''], args[u'']): 43 | project.add_flags(flag_name, flag_value, target_name=args[u'--target'], 44 | configuration_name=args[u'--configuration']) 45 | return u'Flags added successfully.' 46 | 47 | 48 | def _remove(project, args): 49 | for (flag_name, flag_value) in zip(args[u''], args[u'']): 50 | project.remove_flags(flag_name, flag_value, target_name=args[u'--target'], 51 | configuration_name=args[u'--configuration']) 52 | return u'Flags removed successfully.' 53 | 54 | 55 | def main(): 56 | command_parser(execute)(docopt(__doc__)) 57 | 58 | 59 | if __name__ == '__main__': 60 | main() 61 | 62 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxcli/pbxproj_folder.py: -------------------------------------------------------------------------------- 1 | """ 2 | usage: 3 | pbxproj folder [options] [--target ...] 4 | [--exclude ...] 5 | [(--recursive | -r)] 6 | [(--no-create-groups | -G)] 7 | [(--weak | -w)] 8 | [(--no-embed | -E)] 9 | [(--sign-on-copy | -s)] 10 | [(--ignore-unknown-types | -i)] 11 | [(--no-create-build-files | -C)] 12 | [(--header-scope | -H )] 13 | pbxproj folder [options] (--delete | -D) [--tree ] 14 | 15 | positional arguments: 16 | Project path to the .xcodeproj folder. 17 | Path of the file to add to the project. 18 | 19 | generic options: 20 | -h, --help This message. 21 | -t, --target Target name(s) to be modified. If there is no target specified, all targets are 22 | modified. 23 | -b, --backup Creates a backup before start processing the command. 24 | 25 | delete options: 26 | -D, --delete Delete the file. 27 | --tree Tree to add the file relative to. Available options: , , 28 | SOURCE_ROOT, SDKROOT, DEVELOPER_DIR, BUILT_PRODUCTS_DIR. [default: SOURCE_ROOT] 29 | 30 | add options: 31 | -e, --exclude Pattern to exclude during the insertion of a folder. The pattern applies to file 32 | names and folder names. 33 | -r, --recursive Add folders and files recursively. 34 | -G, --no-create-groups Add the folder as a file reference instead of creating group(s). 35 | -w, --weak Add the weak flag when libraries or frameworks are added. Linking optional. 36 | -E, --no-embed Do not embed frameworks when added. 37 | -s, --sign-on-copy Sign frameworks when copied/embedded. 38 | -i, --ignore-unknown-types Ignore unknown file types when added. 39 | -C, --no-create-build-files Do not create build file phases when adding a file. 40 | -H, --header-scope Add header file using the given scope. Available options: public or private, project. 41 | [default: project] 42 | """ 43 | from pbxproj.pbxcli import * 44 | from pbxproj.pbxextensions.ProjectFiles import FileOptions 45 | from docopt import docopt 46 | 47 | 48 | def execute(project, args): 49 | # make a decision of what function to call based on the -D flag 50 | if args[u'--delete']: 51 | return _remove(project, args) 52 | else: 53 | return _add(project, args) 54 | 55 | 56 | def _add(project, args): 57 | if u'--header-scope' not in args or args[u'--header-scope'] not in ['public', 'private', 'project']: 58 | header_scope = u'project' 59 | else: 60 | header_scope = args[u'--header-scope'] 61 | 62 | options = FileOptions(create_build_files=not args[u'--no-create-build-files'], 63 | weak=args[u'--weak'], 64 | ignore_unknown_type=args[u'--ignore-unknown-types'], 65 | embed_framework=not args[u'--no-embed'], 66 | code_sign_on_copy=args[u'--sign-on-copy'], 67 | header_scope=header_scope) 68 | 69 | build_files = project.add_folder(args[u''], excludes=args[u'--exclude'], recursive=args[u'--recursive'], 70 | create_groups=not args[u'--no-create-groups'], target_name=args[u'--target'], 71 | file_options=options) 72 | # print some information about the build files created. 73 | if build_files is None: 74 | raise Exception(u'No files were added to the project.') 75 | 76 | if not build_files: 77 | return u'Folder added to the project, no build file sections created.' 78 | 79 | info = {} 80 | for build_file in build_files: 81 | if build_file.isa not in info: 82 | info[build_file.isa] = 0 83 | info[build_file.isa] += 1 84 | 85 | summary = u'Folder added to the project.' 86 | for k in info: 87 | summary += u'\n{0} {1} sections created.'.format(info[k], k) 88 | return summary 89 | 90 | 91 | def _remove(project, args): 92 | if project.remove_files_by_path(args[u''], tree=args[u'--tree'], target_name=args[u'--target']): 93 | return u'Folder removed from the project.' 94 | raise Exception(u'An error occurred removing one of the files.') 95 | 96 | 97 | def main(): 98 | command_parser(execute)(docopt(__doc__)) 99 | 100 | 101 | if __name__ == '__main__': 102 | main() 103 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxcli/pbxproj_show.py: -------------------------------------------------------------------------------- 1 | """ 2 | usage: 3 | pbxproj show [options] 4 | pbxproj show [options] (--target ...) [(-s | --source-files) | (-H | --header-files) | (-r | --resource-files) | (-f | --framework-files)] 5 | 6 | positional arguments: 7 | Project path to the .xcodeproj folder. 8 | 9 | generic options: 10 | -h, --help This message. 11 | -t, --target Target name to be modified. If there is no target specified, all targets are used. 12 | -b, --backup Creates a backup before start processing the command. 13 | 14 | target options: 15 | -s, --source-files Show the source files attached to the target 16 | -r, --resource-files Show the resource files attached to the target 17 | -f, --framework-files Show the library files attached to the target 18 | -H, --header-files Show the header files attached to the target 19 | -c, --configurations Show the configurations attached to the target 20 | """ 21 | 22 | from pbxproj.pbxcli import * 23 | 24 | def execute(project, args): 25 | # make a decision of what function to call based on the -D flag 26 | if args[u'--target']: 27 | return _target_info(project, args[u'--target'], args) 28 | else: 29 | return _summary(project, args) 30 | 31 | 32 | def _summary(project, args): 33 | info = '' 34 | for target in project.objects.get_targets(): 35 | info += "{name}:\n" \ 36 | "\tProduct name: {productName}\n" \ 37 | "\tConfigurations: {configs}\n" \ 38 | .format(name=target.name, 39 | productName=target.productName, 40 | configs=', '.join([c.name for c in project.objects.get_configurations_on_targets(target.name)]), 41 | ) 42 | 43 | for build_phase_id in target.buildPhases: 44 | build_phase = project.objects[build_phase_id] 45 | info += "\t{name} count: {count}\n"\ 46 | .format(name=build_phase._get_comment(), count=build_phase.files.__len__()) 47 | 48 | info += "\n" 49 | return info 50 | 51 | 52 | def _target_info(project, target_name, args): 53 | build_phases = [] 54 | if args[u'--source-files']: 55 | build_phases += [u'PBXSourcesBuildPhase'] 56 | elif args[u'--header-files']: 57 | build_phases += [u'PBXHeadersBuildPhase'] 58 | elif args[u'--resource-files']: 59 | build_phases += [u'PBXResourcesBuildPhase'] 60 | elif args[u'--framework-files']: 61 | build_phases += [u'PBXFrameworksBuildPhase'] 62 | 63 | info = '' 64 | for target in project.objects.get_targets(target_name): 65 | info += "{name}:\n" \ 66 | "\tProduct name: {productName}\n" \ 67 | .format(name=target.name, 68 | productName=target.productName, 69 | configs=', '.join([c.name for c in project.objects.get_configurations_on_targets(target.name)]), 70 | ) 71 | 72 | if args[u'--configurations']: 73 | info += "\tConfigurations: {configs}\n" \ 74 | .format(configs=', '.join([c.name for c in project.objects.get_configurations_on_targets(target.name)])) 75 | 76 | for build_phase_id in target.buildPhases: 77 | build_phase = project.objects[build_phase_id] 78 | if build_phase.isa in build_phases: 79 | info += "\t{name}: \n\t\t".format(name=build_phase._get_comment()) 80 | files = [] 81 | for build_file_id in build_phase.files: 82 | build_file = project.objects[build_file_id] 83 | files.append(project.objects[build_file.fileRef]._get_comment()) 84 | info += '{files}\n'.format(files="\n\t\t".join(sorted(files))) 85 | info += '\n' 86 | return info 87 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxextensions/__init__.py: -------------------------------------------------------------------------------- 1 | from pbxproj.pbxextensions.ProjectFiles import * 2 | from pbxproj.pbxextensions.ProjectFlags import * 3 | from pbxproj.pbxextensions.ProjectGroups import * 4 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXAggregateTarget.py: -------------------------------------------------------------------------------- 1 | from pbxproj.pbxsections.PBXGenericTarget import * 2 | 3 | 4 | class PBXAggregateTarget(PBXGenericTarget): 5 | pass 6 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXBuildFile.py: -------------------------------------------------------------------------------- 1 | from pbxproj import * 2 | 3 | 4 | class PBXBuildFile(PBXGenericObject): 5 | @classmethod 6 | def create(cls, file_ref, attributes=None, compiler_flags=None): 7 | return cls().parse({ 8 | u'_id': cls._generate_id(), 9 | u'isa': cls.__name__, 10 | u'fileRef': file_ref.get_id(), 11 | u'settings': cls._get_settings(attributes, compiler_flags) 12 | }) 13 | 14 | @classmethod 15 | def _get_settings(cls, attributes=None, compiler_flags=None): 16 | if attributes is None and compiler_flags is None: 17 | return None 18 | 19 | settings = {} 20 | if attributes is not None: 21 | if not isinstance(attributes, list): 22 | attributes = [attributes] 23 | settings[u'ATTRIBUTES'] = attributes 24 | 25 | if compiler_flags is not None: 26 | if not isinstance(compiler_flags, list): 27 | compiler_flags = [compiler_flags] 28 | settings[u'COMPILER_FLAGS'] = u' '.join(compiler_flags) 29 | 30 | return settings 31 | 32 | def _print_object(self, indentation_depth=u'', entry_separator=u'\n', object_start=u'\n', 33 | indentation_increment=u'\t'): 34 | return super(PBXBuildFile, self)._print_object(u'', entry_separator=u' ', object_start=u'', 35 | indentation_increment=u'') 36 | 37 | def _get_comment(self): 38 | return u'{0} in {1}'.format(self.fileRef._get_comment(), self._get_section()) 39 | 40 | def _get_section(self): 41 | objects = self.get_parent() 42 | target = self.get_id() 43 | 44 | for section in objects.get_sections(): 45 | for obj in objects.get_objects_in_section(section): 46 | if u'files' in obj and target in obj.files: 47 | return obj._get_comment() 48 | 49 | def add_attributes(self, attributes): 50 | if not isinstance(attributes, list): 51 | attributes = [attributes] 52 | 53 | if u'settings' not in self: 54 | self[u'settings'] = PBXGenericObject() 55 | 56 | if u'ATTRIBUTES' not in self.settings: 57 | self.settings[u'ATTRIBUTES'] = PBXList() 58 | 59 | # append, if it's assigned and the list only has 1 element it will turn it into a string 60 | self.settings.ATTRIBUTES += attributes 61 | 62 | def remove_attributes(self, attributes): 63 | if u'settings' not in self or u'ATTRIBUTES' not in self.settings: 64 | # nothing to remove 65 | return False 66 | 67 | if not isinstance(attributes, list): 68 | attributes = [attributes] 69 | 70 | for attribute in self.settings.ATTRIBUTES: 71 | self.settings.ATTRIBUTES.remove(attribute) 72 | 73 | return self._clean_up_settings() 74 | 75 | def add_compiler_flags(self, compiler_flags): 76 | if isinstance(compiler_flags, list): 77 | compiler_flags = u' '.join(compiler_flags) 78 | 79 | if u'settings' not in self: 80 | self[u'settings'] = PBXGenericObject() 81 | 82 | if u'COMPILER_FLAGS' not in self.settings: 83 | self.settings[u'COMPILER_FLAGS'] = u'' 84 | 85 | self.settings[u'COMPILER_FLAGS'] += u' ' + compiler_flags 86 | self.settings[u'COMPILER_FLAGS'] = self.settings[u'COMPILER_FLAGS'].strip() 87 | 88 | def remove_compiler_flags(self, compiler_flags): 89 | if u'settings' not in self or u'COMPILER_FLAGS' not in self.settings: 90 | # nothing to remove 91 | return False 92 | 93 | if not isinstance(compiler_flags, list): 94 | compiler_flags = [compiler_flags] 95 | 96 | for flag in compiler_flags: 97 | self.settings[u'COMPILER_FLAGS'] = self.settings[u'COMPILER_FLAGS'].replace(flag, u'') 98 | self.settings[u'COMPILER_FLAGS'] = self.settings[u'COMPILER_FLAGS'].strip() 99 | 100 | return self._clean_up_settings() 101 | 102 | def _clean_up_settings(self): 103 | # no attributes remain, remove the element 104 | if u'ATTRIBUTES' in self.settings and self.settings.ATTRIBUTES.__len__() == 0: 105 | del self.settings[u'ATTRIBUTES'] 106 | 107 | # no flags remain, remove the element 108 | if u'COMPILER_FLAGS' in self.settings and self.settings.COMPILER_FLAGS.__len__() == 0: 109 | del self.settings[u'COMPILER_FLAGS'] 110 | 111 | if self.settings.get_keys().__len__() == 0: 112 | del self[u'settings'] 113 | 114 | return True 115 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXContainerItemProxy.py: -------------------------------------------------------------------------------- 1 | from pbxproj import PBXGenericObject 2 | 3 | 4 | class PBXContainerItemProxy(PBXGenericObject): 5 | @classmethod 6 | def create(cls, file_ref, remote_ref, proxy_type=2): 7 | return cls().parse({ 8 | u'_id': cls._generate_id(), 9 | u'isa': cls.__name__, 10 | u'containerPortal': file_ref.get_id(), 11 | u'proxyType': proxy_type, 12 | u'remoteGlobalIDString': remote_ref.productReference, 13 | u'remoteInfo': remote_ref.productName 14 | }) 15 | 16 | def _get_comment(self): 17 | return u'PBXContainerItemProxy' 18 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXCopyFilesBuildPhase.py: -------------------------------------------------------------------------------- 1 | from pbxproj.pbxsections.PBXGenericBuildPhase import * 2 | 3 | 4 | class PBXCopyFilesBuildPhaseNames: 5 | EMBEDDED_FRAMEWORKS = u'Embed Frameworks' 6 | 7 | 8 | class PBXCopyFilesBuildPhase(PBXGenericBuildPhase): 9 | @classmethod 10 | def create(cls, name=None, files=None, dest_path=u'', dest_subfolder_spec='10'): 11 | return cls().parse({ 12 | u'_id': cls._generate_id(), 13 | u'isa': cls.__name__, 14 | u'name': name, 15 | u'files': files if files else [], 16 | u'buildActionMask': 0x7FFFFFFF, 17 | u'dstSubfolderSpec': dest_subfolder_spec, 18 | u'dstPath': dest_path, 19 | u'runOnlyForDeploymentPostprocessing': 0 20 | }) 21 | 22 | def _get_comment(self): 23 | comment = super(PBXCopyFilesBuildPhase, self)._get_comment() 24 | if comment is None: 25 | return u'CopyFiles' 26 | return comment 27 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXFileReference.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pbxproj import PBXGenericObject 3 | 4 | 5 | class PBXFileReference(PBXGenericObject): 6 | @classmethod 7 | def create(cls, path, tree=u'SOURCE_ROOT'): 8 | return cls().parse({ 9 | u'_id': cls._generate_id(), 10 | u'isa': cls.__name__, 11 | u'path': path, 12 | u'name': os.path.split(path)[1], 13 | u'sourceTree': tree 14 | }) 15 | 16 | def set_explicit_file_type(self, file_type): 17 | if u'lastKnownFileType' in self: 18 | del self[u'lastKnownFileType'] 19 | self[u'explicitFileType'] = file_type 20 | 21 | def set_last_known_file_type(self, file_type): 22 | if u'explicitFileType' in self: 23 | del self[u'explicitFileType'] 24 | self[u'lastKnownFileType'] = file_type 25 | 26 | def get_file_type(self): 27 | if u'explicitFileType' in self: 28 | return self.explicitFileType 29 | return self.lastKnownFileType 30 | 31 | def _print_object(self, indentation_depth=u'', entry_separator=u'\n', object_start=u'\n', 32 | indentation_increment=u'\t'): 33 | return super(PBXFileReference, self)._print_object(u'', entry_separator=u' ', object_start=u'', 34 | indentation_increment=u'') 35 | 36 | def get_name(self): 37 | if hasattr(self, u'name'): 38 | return self.name 39 | if hasattr(self, u'path'): 40 | return self.path 41 | return None 42 | 43 | def remove(self, recursive=True): 44 | # search on the BuildFiles if there is a build file to be removed, and remove it 45 | # search for each phase that has a reference to the build file and remove it from it. 46 | # remove the file reference from it's parent 47 | pass 48 | 49 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXFrameworksBuildPhase.py: -------------------------------------------------------------------------------- 1 | from pbxproj.pbxsections.PBXGenericBuildPhase import * 2 | 3 | 4 | class PBXFrameworksBuildPhase(PBXGenericBuildPhase): 5 | def _get_comment(self): 6 | return u'Frameworks' 7 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXGenericBuildPhase.py: -------------------------------------------------------------------------------- 1 | from pbxproj.pbxsections.PBXBuildFile import * 2 | 3 | 4 | class PBXGenericBuildPhase(PBXGenericObject): 5 | @classmethod 6 | def create(cls, name=None, files=None): 7 | return cls().parse({ 8 | u'_id': cls._generate_id(), 9 | u'isa': cls.__name__, 10 | u'name': name, 11 | u'files': files if files else [], 12 | u'buildActionMask': 0x7FFFFFFF, 13 | u'runOnlyForDeploymentPostprocessing': 0 14 | }) 15 | 16 | def add_build_file(self, build_file): 17 | if not isinstance(build_file, PBXBuildFile): 18 | return False 19 | 20 | self.files.append(build_file.get_id()) 21 | return True 22 | 23 | def remove_build_file(self, build_file): 24 | if not isinstance(build_file, PBXBuildFile): 25 | return False 26 | 27 | self.files.remove(build_file.get_id()) 28 | del self.get_parent()[build_file.get_id()] 29 | 30 | return True 31 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXGenericTarget.py: -------------------------------------------------------------------------------- 1 | from pbxproj.PBXGenericObject import * 2 | from pbxproj.pbxsections.PBXGenericBuildPhase import * 3 | 4 | 5 | class PBXGenericTarget(PBXGenericObject): 6 | def get_or_create_build_phase(self, build_phase_type, search_parameters=None, create_parameters=()): 7 | result = [] 8 | parent = self.get_parent() 9 | search_parameters = search_parameters if search_parameters is not None else {} 10 | 11 | if build_phase_type is None: 12 | return result 13 | 14 | for build_phase_id in self.buildPhases: 15 | target_build_phase = parent[build_phase_id] 16 | current_build_phase = target_build_phase.isa 17 | 18 | if current_build_phase == build_phase_type and \ 19 | all(key in target_build_phase and target_build_phase[key] == search_parameters[key] for key in search_parameters): 20 | result.append(target_build_phase) 21 | 22 | if result.__len__() == 0: 23 | build_phase = self._get_class_reference(build_phase_type).create(*create_parameters) 24 | parent[build_phase.get_id()] = build_phase 25 | self.add_build_phase(build_phase) 26 | result.append(build_phase) 27 | 28 | return result 29 | 30 | def add_build_phase(self, build_phase, position=None): 31 | if position is None: 32 | position = self.buildPhases.__len__() 33 | 34 | self.buildPhases.insert(position, build_phase.get_id()) 35 | 36 | def remove_build_phase(self, build_phase): 37 | if not isinstance(build_phase, PBXGenericBuildPhase): 38 | return False 39 | 40 | self.buildPhases.remove(build_phase.get_id()) 41 | del self.get_parent()[build_phase.get_id()] 42 | 43 | return True 44 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXGroup.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | from __future__ import print_function 3 | from __future__ import division 4 | from __future__ import absolute_import 5 | from future import standard_library 6 | standard_library.install_aliases() 7 | from past.builtins import basestring 8 | 9 | from pbxproj.PBXGenericObject import * 10 | from pbxproj.pbxsections import * 11 | 12 | 13 | class PBXGroup(PBXGenericObject): 14 | @classmethod 15 | def create(cls, path=None, name=None, tree=u'', children=None): 16 | return cls().parse({ 17 | u'_id': cls._generate_id(), 18 | u'isa': cls.__name__, 19 | u'children': children if children else [], 20 | u'name': name, 21 | u'path': path, 22 | u'sourceTree': tree 23 | }) 24 | 25 | def get_name(self): 26 | if u'name' in self: 27 | return self.name 28 | if u'path' in self: 29 | return self.path 30 | return None 31 | 32 | def get_path(self): 33 | if u'path' in self: 34 | return self.path 35 | if u'name' in self: 36 | return self.name 37 | return None 38 | 39 | def has_child(self, child): 40 | """ 41 | Checks if the given child id 42 | :param child: The id to check if it's a child of the group 43 | :return: True if the given id it's a child of this group, False otherwise 44 | """ 45 | if u'children' not in self: 46 | return False 47 | 48 | if not isinstance(child, basestring): 49 | child = child.get_id() 50 | 51 | return child in self.children 52 | 53 | def add_child(self, child): 54 | # if it's not the right type of children for the group 55 | if not isinstance(child, PBXGroup) \ 56 | and not isinstance(child, PBXFileReference) \ 57 | and not isinstance(child, PBXReferenceProxy): 58 | return False 59 | 60 | self.children.append(child.get_id()) 61 | return True 62 | 63 | def remove_child(self, child): 64 | if self.has_child(child): 65 | self.children.remove(child.get_id()) 66 | return True 67 | 68 | return False 69 | 70 | def remove(self, recursive=True): 71 | parent = self.get_parent() 72 | # remove from the objects reference 73 | del parent[self.get_id()] 74 | 75 | # remove children if necessary 76 | if recursive: 77 | for subgroup_id in self.children: 78 | subgroup = parent[subgroup_id] 79 | if subgroup is None or not subgroup.remove(recursive): 80 | return False 81 | 82 | return True 83 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXHeadersBuildPhase.py: -------------------------------------------------------------------------------- 1 | from pbxproj.pbxsections.PBXGenericBuildPhase import * 2 | 3 | 4 | class PBXHeadersBuildPhase(PBXGenericBuildPhase): 5 | def _get_comment(self): 6 | return u'Headers' 7 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXLegacyTarget.py: -------------------------------------------------------------------------------- 1 | from pbxproj.pbxsections.PBXGenericTarget import PBXGenericTarget 2 | 3 | 4 | class PBXLegacyTarget(PBXGenericTarget): 5 | pass 6 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXNativeTarget.py: -------------------------------------------------------------------------------- 1 | from pbxproj.pbxsections.PBXGenericTarget import PBXGenericTarget 2 | 3 | 4 | class PBXNativeTarget(PBXGenericTarget): 5 | pass 6 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXProject.py: -------------------------------------------------------------------------------- 1 | from pbxproj import PBXGenericObject 2 | 3 | 4 | class PBXProvioningTypes: 5 | MANUAL = u'Manual' 6 | AUTOMATIC = u'Automatic' 7 | 8 | 9 | class PBXProject(PBXGenericObject): 10 | def _get_comment(self): 11 | return u'Project object' 12 | 13 | def set_provisioning_style(self, provisioning_type, target): 14 | if u'attributes' not in self: 15 | self[u'attributes'] = PBXGenericObject() 16 | 17 | if u'TargetAttributes' not in self.attributes: 18 | self.attributes[u'TargetAttributes'] = PBXGenericObject() 19 | 20 | if target.get_id() not in self.attributes.TargetAttributes: 21 | self.attributes.TargetAttributes[target.get_id()] = PBXGenericObject() 22 | 23 | self.attributes.TargetAttributes[target.get_id()][u'ProvisioningStyle'] = provisioning_type 24 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXReferenceProxy.py: -------------------------------------------------------------------------------- 1 | from pbxproj import PBXGenericObject 2 | 3 | 4 | class PBXReferenceProxy(PBXGenericObject): 5 | @classmethod 6 | def create(cls, file_ref, remote_ref, tree=u'BUILT_PRODUCTS_DIR'): 7 | return cls().parse({ 8 | u'_id': cls._generate_id(), 9 | u'isa': cls.__name__, 10 | u'path': file_ref.path, 11 | u'fileType': file_ref.get_file_type(), 12 | u'remoteRef': remote_ref.get_id(), 13 | u'sourceTree': tree 14 | }) 15 | 16 | def get_file_type(self): 17 | return self.fileType 18 | 19 | def get_name(self): 20 | return self.path 21 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXResourcesBuildPhase.py: -------------------------------------------------------------------------------- 1 | from pbxproj.pbxsections.PBXGenericBuildPhase import * 2 | 3 | 4 | class PBXResourcesBuildPhase(PBXGenericBuildPhase): 5 | def _get_comment(self): 6 | return u'Resources' 7 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXShellScriptBuildPhase.py: -------------------------------------------------------------------------------- 1 | from pbxproj.pbxsections.PBXGenericBuildPhase import * 2 | 3 | 4 | class PBXShellScriptBuildPhase(PBXGenericBuildPhase): 5 | @classmethod 6 | def create(cls, script, shell_path=u"/bin/sh", files=None, input_paths=None, output_paths=None, show_in_log='0'): 7 | return cls().parse({ 8 | u'_id': cls._generate_id(), 9 | u'isa': cls.__name__, 10 | u'files': files if files else [], 11 | u'buildActionMask': 0x7FFFFFFF, 12 | u'inputPaths': input_paths if input_paths else [], 13 | u'outputPaths': output_paths if output_paths else [], 14 | u'runOnlyForDeploymentPostprocessing': 0, 15 | u'shellPath': shell_path, 16 | u'shellScript': script, 17 | u'showEnvVarsInLog': show_in_log 18 | }) 19 | 20 | def _get_comment(self): 21 | return u'ShellScript' 22 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXSourcesBuildPhase.py: -------------------------------------------------------------------------------- 1 | from pbxproj.pbxsections.PBXGenericBuildPhase import * 2 | 3 | 4 | class PBXSourcesBuildPhase(PBXGenericBuildPhase): 5 | def _get_comment(self): 6 | return u'Sources' 7 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/PBXTargetDependency.py: -------------------------------------------------------------------------------- 1 | from pbxproj import PBXGenericObject 2 | 3 | 4 | class PBXTargetDependency(PBXGenericObject): 5 | def _get_comment(self): 6 | return u'PBXTargetDependency' 7 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/XCBuildConfiguration.py: -------------------------------------------------------------------------------- 1 | import os 2 | from collections import OrderedDict 3 | from pbxproj import PBXGenericObject 4 | 5 | 6 | class XCBuildConfigurationFlags: 7 | OTHER_CFLAGS = u'OTHER_CFLAGS' 8 | OTHER_LDFLAGS = u'OTHER_LDFLAGS' 9 | HEADER_SEARCH_PATHS = u'HEADER_SEARCH_PATHS' 10 | LIBRARY_SEARCH_PATHS = u'LIBRARY_SEARCH_PATHS' 11 | FRAMEWORK_SEARCH_PATHS = u'FRAMEWORK_SEARCH_PATHS' 12 | LD_RUNPATH_SEARCH_PATHS = u'LD_RUNPATH_SEARCH_PATHS' 13 | 14 | 15 | class XCBuildConfiguration(PBXGenericObject): 16 | 17 | def add_flags(self, flag_name, flags): 18 | if u'buildSettings' not in self: 19 | self[u'buildSettings'] = PBXGenericObject() 20 | 21 | current_flags = self.buildSettings[flag_name] 22 | if current_flags is None: 23 | self.set_flags(flag_name, flags) 24 | return 25 | 26 | if not isinstance(current_flags, list): 27 | current_flags = [current_flags] 28 | 29 | if not isinstance(flags, list): 30 | flags = [flags] 31 | 32 | self.set_flags(flag_name, current_flags + flags) 33 | 34 | def set_flags(self, flag_name, flags): 35 | if u'buildSettings' not in self: 36 | self[u'buildSettings'] = PBXGenericObject() 37 | 38 | if not isinstance(flags, list): 39 | flags = [flags] 40 | 41 | self.buildSettings[flag_name] = list(OrderedDict.fromkeys(flags)) 42 | 43 | def remove_flags(self, flag_name, flags): 44 | if u'buildSettings' not in self or self.buildSettings[flag_name] is None: 45 | # nothing to remove 46 | return False 47 | 48 | current_flags = self.buildSettings[flag_name] 49 | if not isinstance(current_flags, list): 50 | current_flags = [current_flags] 51 | 52 | if flags is None: 53 | flags = current_flags 54 | 55 | if not isinstance(flags, list): 56 | flags = [flags] 57 | 58 | self.buildSettings[flag_name] = [x for x in current_flags if x not in flags] 59 | return True 60 | 61 | def add_search_paths(self, key, paths, recursive=False, escape=False): 62 | if not isinstance(paths, list): 63 | paths = [paths] 64 | 65 | # build the recursive/escaped strings and add the flags accordingly 66 | flags = [] 67 | for path in paths: 68 | if path == '$(inherited)': 69 | escape = False 70 | recursive = False 71 | 72 | if escape: 73 | path = u'"{0}"'.format(path) 74 | 75 | if recursive and not path.endswith('/**'): 76 | path = os.path.join(path, '**') 77 | 78 | flags.append(path) 79 | 80 | self.add_flags(key, flags) 81 | 82 | def remove_search_paths(self, key, paths): 83 | return self.remove_flags(key, paths) 84 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/XCConfigurationList.py: -------------------------------------------------------------------------------- 1 | from pbxproj import PBXGenericObject 2 | 3 | 4 | class XCConfigurationList(PBXGenericObject): 5 | def _get_comment(self): 6 | info = self._get_section() 7 | return u'Build configuration list for {0} "{1}"'.format(*info) 8 | 9 | def _get_section(self): 10 | objects = self.get_parent() 11 | target = self.get_id() 12 | 13 | for obj in objects.get_objects_in_section(u'PBXNativeTarget', u'PBXAggregateTarget'): 14 | if target in obj.buildConfigurationList: 15 | return obj.isa, obj.name 16 | 17 | for obj in objects.get_objects_in_section(u'PBXProject'): 18 | if target in obj.buildConfigurationList: 19 | return obj.isa, objects[obj.targets[0]].productName 20 | 21 | return u'', u'' 22 | -------------------------------------------------------------------------------- /xcode_build/pbxproj/pbxsections/__init__.py: -------------------------------------------------------------------------------- 1 | from pbxproj.pbxsections.PBXBuildFile import * 2 | from pbxproj.pbxsections.PBXFileReference import * 3 | from pbxproj.pbxsections.PBXFrameworksBuildPhase import * 4 | from pbxproj.pbxsections.PBXProject import * 5 | from pbxproj.pbxsections.PBXResourcesBuildPhase import * 6 | from pbxproj.pbxsections.PBXSourcesBuildPhase import * 7 | from pbxproj.pbxsections.XCConfigurationList import * 8 | from pbxproj.pbxsections.PBXContainerItemProxy import * 9 | from pbxproj.pbxsections.PBXCopyFilesBuildPhase import * 10 | from pbxproj.pbxsections.PBXShellScriptBuildPhase import * 11 | from pbxproj.pbxsections.PBXTargetDependency import * 12 | from pbxproj.pbxsections.PBXHeadersBuildPhase import * 13 | from pbxproj.pbxsections.XCBuildConfiguration import * 14 | from pbxproj.pbxsections.PBXAggregateTarget import * 15 | from pbxproj.pbxsections.PBXNativeTarget import * 16 | from pbxproj.pbxsections.PBXLegacyTarget import * 17 | from pbxproj.pbxsections.PBXReferenceProxy import * 18 | from pbxproj.pbxsections.PBXGroup import * 19 | -------------------------------------------------------------------------------- /xcode_build/requirements.txt: -------------------------------------------------------------------------------- 1 | altgraph==0.16.1 2 | astroid==1.6.6 3 | backports.functools-lru-cache==1.5 4 | configparser==3.7.4 5 | dis3==0.1.3 6 | enum34==1.1.6 7 | future==0.17.1 8 | futures==3.2.0 9 | isort==4.3.21 10 | lazy-object-proxy==1.4.1 11 | machobot==0.1.5 12 | macholib==1.11 13 | mccabe==0.6.1 14 | openstep-parser==1.3.1 15 | pefile==2019.4.18 16 | Pillow==6.1.0 17 | PyInstaller==3.4 18 | pylint==1.9.4 19 | singledispatch==3.4.0.3 20 | six==1.12.0 21 | virtualenv==16.6.1 22 | wrapt==1.11.2 23 | biplist==1.0.1 24 | -------------------------------------------------------------------------------- /xcode_build/start_python_venv.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import os 3 | import shutil 4 | import time 5 | import subprocess 6 | 7 | #Git下载代码后,开始部署虚拟环境并激活 8 | def start_python_venv(): 9 | os.chdir('%s'%(os.getcwd())) 10 | os.system('virtualenv %s'%('venv')) 11 | os.chdir('%s'%('venv')) 12 | os.system('pwd') 13 | os.system('source ./bin/activate') 14 | os.system('pip install -r ../requirements.txt') 15 | 16 | def ready_push_git(): 17 | os.chdir('%s/venv'%(os.getcwd())) 18 | os.system('pip freeze > ../requirements.txt') 19 | shutil.rmtree(os.getcwd()) 20 | 21 | def venv_deactivate(): 22 | os.system('deactivate') 23 | 24 | -------------------------------------------------------------------------------- /xcode_build/xcode_build.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import optparse 3 | import os 4 | import sys 5 | import getpass 6 | import json 7 | import hashlib 8 | import smtplib 9 | import commands 10 | import subprocess 11 | import shutil 12 | # import appicon_generate 13 | from xcode_build_module import XCodeBuild 14 | 15 | #主函数 16 | def main(): 17 | # print buildArchivePath('project_test') 18 | # return 19 | # print "sys.path[0]:",sys.path[0] 20 | # print "sys.path[1]:",sys.path[1] 21 | # print "sys.argv[0]:scriptPath:", sys.argv[0] 22 | # print "sys.argv[1]:argv[1]:", sys.argv[1] 23 | # print "sys.argv[2]:argv[2]:", sys.argv[2] 24 | # print "len(sys.argv):",len(sys.argv) 25 | # setProjectAppDisplayName('firstBuild121414') 26 | #开始打包 27 | test() 28 | 29 | def test(projectPathList): 30 | #appicon图片存储路径 31 | # appicon_path=mainPath+"/project_test/Assets.xcassets/AppIcon.appiconset" 32 | current_work_path=os.getcwd() 33 | for index in range(0,len(projectPathList)): 34 | projectPath=projectPathList[index] 35 | xcode_build=XCodeBuild(projectPath, projectPath+"/project_test/Info.plist", 36 | True,"project_test","Release","iPhone Distribution: nanxing liao (73889W623Z)",current_work_path+"/provisioning_profile/project_test_dis_provisioning_profile.mobileprovision",current_work_path+"/exportOptions.plist") 37 | xcode_build.checkWorkSpace() 38 | xcode_build.allowFinder() 39 | xcode_build.allowKeychain() 40 | xcode_build.clearPbxproj() 41 | xcode_build.cleanPro() 42 | if index==0 or index>4: 43 | pass 44 | else: 45 | sdk_functions={ 46 | 1:lambda :xcode_build.embedAssignSDK('Adcolony'), 47 | 2:lambda :xcode_build.embedAssignSDK('Adview'), 48 | 3:lambda :xcode_build.embedAssignSDK('Facebook'), 49 | 4:lambda :xcode_build.embedAssignSDK('Youmi') 50 | } 51 | func=sdk_functions[index] 52 | func() 53 | xcode_build.buildApp() 54 | return 55 | 56 | current_work_path=os.getcwd() 57 | projecttest_path=current_work_path+"/project_test" 58 | 59 | projectPathList=[projecttest_path] 60 | for index in range(0,4): 61 | resultPath=projecttest_path+"/../backup%s"%(index) 62 | try: 63 | shutil.rmtree(resultPath) 64 | except BaseException: 65 | pass 66 | # print 'error!' 67 | pass 68 | 69 | for index in range(0,4): 70 | resultPath=projecttest_path+"/../backup%s"%(index) 71 | try: 72 | shutil.copytree(projecttest_path, resultPath) 73 | except BaseException: 74 | pass 75 | # print 'error.' 76 | finally: 77 | projectPathList.append(resultPath) 78 | pass 79 | 80 | test(projectPathList) 81 | # ImgManager.sharedinstance().handle_icon_images() 82 | # generateAppIcons() 83 | --------------------------------------------------------------------------------