├── src
├── .idea
│ ├── misc.xml
│ ├── vcs.xml
│ ├── modules.xml
│ ├── DDNS.iml
│ └── workspace.xml
├── config.json
├── CommonRequestSingleton.py
├── AcsClientSingleton.py
├── IpGetter.py
├── DDNS.py
└── Utils.py
├── README_ZH_CN.md
├── README.md
└── LICENSE
/src/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "AccessKeyId": "Your_AccessKeyId",
3 | "AccessKeySecret": "Your_AccessKeySecret",
4 | "First-level-domain": "Your_First-level-domain",
5 | "Second-level-domain": "Your_Second-level-domain"
6 | }
--------------------------------------------------------------------------------
/src/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/.idea/DDNS.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/CommonRequestSingleton.py:
--------------------------------------------------------------------------------
1 | '''
2 | 获取阿里云Common Request请求类
3 | 单实例
4 | Created By Martin Huang on 2018/5/26
5 | '''
6 | from aliyunsdkcore.request import CommonRequest
7 |
8 | class CommonRequestSing:
9 | #私有类变量
10 | __request = None
11 |
12 | #该修饰符将实例方法变成类方法
13 | #,因为类方法无法操作私有的类变量,所以使用实例方法进行操作,再进行转换为类方法
14 | @classmethod
15 | def getInstance(self):
16 | if self.__request is None:
17 | self.__request = CommonRequest()
18 | return self.__request
19 |
20 | if __name__ == "__main__":
21 | CommonRequestSing.getInstance()
22 |
--------------------------------------------------------------------------------
/src/AcsClientSingleton.py:
--------------------------------------------------------------------------------
1 | '''
2 | @desc:AcsClient的单实例类
3 | @author: Martin Huang
4 | @time: created on 2018/5/26 18:50
5 | @修改记录:
6 | 2018/6/10 =》 AccessKeyId 和 AccessKeySecret从配置文件中读取
7 | '''
8 | from aliyunsdkcore.client import AcsClient
9 | import Utils as tools
10 | class AcsClientSing:
11 | __client = None
12 |
13 | @classmethod
14 | def getInstance(self):
15 | if self.__client is None:
16 | acsDict = tools.Utils.getConfigJson()
17 | self.__client = AcsClient(acsDict.get('AccessKeyId'), acsDict.get('AccessKeySecret'), 'cn-hangzhou')
18 | return self.__client
19 |
--------------------------------------------------------------------------------
/src/IpGetter.py:
--------------------------------------------------------------------------------
1 | '''
2 | 获取用户真实IP地址
3 | Created By Martin Huang on 2018/5/19
4 | 修改记录:
5 | 2018/12/24 =》改进ip获取方式 取消BS4依赖 感谢@Nielamu的建议
6 | 2020/05/05 =》改进ipv4获取方式,如果获取失败,则会写入日志文件,并过10秒后使用新的网址重试,感谢@sunsheho贡献的代码
7 | 我在休眠时间上略作修改
8 | '''
9 | import urllib.request
10 | from urllib import request,error
11 | import json
12 | import time,datetime
13 | from time import sleep
14 |
15 | def senderror(errcont):
16 | enow=datetime.datetime.now()
17 | now=enow.strftime('%Y-%m-%d %H:%M:%S')
18 | errfile=open('DDNS.log','a')
19 | errfile.write(now)
20 | errfile.write(str(errcont))
21 | errfile.write('\n')
22 | errfile.close()
23 |
24 |
25 |
26 | def getIpPage():
27 | try:
28 | url = "https://api.ipify.org/?format=json"
29 | response = request.urlopen(url,timeout=60)
30 | html = response.read().decode('utf-8')
31 | return html
32 | except error.HTTPError as e:
33 | print(e.reason)
34 | senderror(e.reason)
35 | time.sleep(10)
36 | getIpPage()
37 | except error.URLError as e:
38 | print(e.reason)
39 | senderror(e.reason)
40 | time.sleep(10)
41 | getIpPage()
42 | except:
43 | url = "http://members.3322.org/dyndns/getip"
44 | response = request.urlopen(url,timeout=60)
45 | html = response.read().decode('utf-8')
46 | html = html.replace("\n","")
47 | htm={}
48 | htm['ip'] = html
49 | HTL = json.dumps(htm)
50 | return HTL
51 |
52 | # 解析数据,获得IP
53 | def getRealIp(data):
54 | try:
55 | jsonData = json.loads(data)
56 | return jsonData['ip']
57 | except:
58 | time.sleep(200)
59 | getIpPage()
60 |
61 |
62 | # 利用API获取含有用户ip的JSON数据
63 | def getIpPageV6():
64 | url = "https://v6.ident.me/.json"
65 | response = urllib.request.urlopen(url)
66 | html = response.read().decode('utf-8')
67 | return html
68 |
69 |
70 | # 解析数据,获得IP
71 | def getRealIpV6(data):
72 | jsonData = json.loads(data)
73 | return jsonData['address']
74 |
--------------------------------------------------------------------------------
/src/DDNS.py:
--------------------------------------------------------------------------------
1 | '''
2 | DDNS 主程序 使用阿里云的SDK发起请求
3 | Created By Martin Huang on 2018/5/20
4 | 修改记录:
5 | 2018/5/20 => 第一版本
6 | 2018/5/26 => 增加异常处理、Requst使用单例模式,略有优化
7 | 2018/5/29 => 增加网络连通性检测,只有联通时才进行操作,否则等待
8 | 2018/6/10 => 使用配置文件存储配置,避免代码内部修改(需要注意Python模块相互引用问题)
9 | 2018/9/24 => 修改失败提示信息
10 | '''
11 | from aliyunsdkcore.acs_exception.exceptions import ServerException
12 | from aliyunsdkcore.acs_exception.exceptions import ClientException
13 | from Utils import Utils
14 | import time
15 | import argparse
16 |
17 | def DDNS(use_v6):
18 | client = Utils.getAcsClient()
19 | recordId = Utils.getRecordId(Utils.getConfigJson().get('Second-level-domain'))
20 | if use_v6:
21 | ip = Utils.getRealIPv6()
22 | type = 'AAAA'
23 | else:
24 | ip = Utils.getRealIP()
25 | type = 'A'
26 | print({'type': type, 'ip':ip})
27 |
28 | request = Utils.getCommonRequest()
29 | request.set_domain('alidns.aliyuncs.com')
30 | request.set_version('2015-01-09')
31 | request.set_action_name('UpdateDomainRecord')
32 | request.add_query_param('RecordId', recordId)
33 | request.add_query_param('RR', Utils.getConfigJson().get('Second-level-domain'))
34 | request.add_query_param('Type', type)
35 | request.add_query_param('Value', ip)
36 | response = client.do_action_with_exception(request)
37 | return response
38 |
39 | if __name__ == "__main__":
40 | parser = argparse.ArgumentParser(description='DDNS')
41 | parser.add_argument('-6', '--ipv6', nargs='*', default=False)
42 | args = parser.parse_args()
43 | isipv6 = isinstance(args.ipv6, list)
44 |
45 | try:
46 | while not Utils.isOnline():
47 | time.sleep(3)
48 | continue
49 | result = DDNS(isipv6)
50 | print("成功!")
51 | except (ServerException,ClientException) as reason:
52 | print("失败!原因为")
53 | print(reason.get_error_msg())
54 | print("可参考:https://help.aliyun.com/document_detail/29774.html?spm=a2c4g.11186623.2.20.fDjexq#%E9%94%99%E8%AF%AF%E7%A0%81")
55 | print("或阿里云帮助文档")
--------------------------------------------------------------------------------
/README_ZH_CN.md:
--------------------------------------------------------------------------------
1 | # DDNS
2 |
3 | [中文](https://github.com/mgsky1/DDNS/blob/master/README_ZH_CN.md)|[English](https://github.com/mgsky1/DDNS/blob/master/README.md)
4 |
5 | ## Summary
6 |
7 | > 利用Python和阿里云云解析API实现。可利用于家庭环境,向公网映射NAS,DB,Web等应用
8 |
9 | ## Install
10 |
11 | ```bash
12 | pip3 install aliyun-python-sdk-core-v3
13 | ```
14 |
15 | ## Run
16 | ```bash
17 | python3 src/DDNS.py # 默认ipv4
18 | python3 src/DDNS.py -6 # 改用ipv6
19 | ```
20 |
21 |
22 | ## Note
23 | > * 基于:Python 3 、阿里云Python SDK、阿里云云解析API
24 | > * 直接运行DDNS.py文件的main函数即可,其他的py文件的main函数都为测试
25 | > * 可将此脚本设置为系统定时任务,例如每天凌晨4:30执行一次或者每次联网时自动执行一次
26 | > * *在最新的[dev](https://github.com/mgsky1/DDNS/tree/dev)分支中增加了同一IP同时绑定多个域名的功能,欢迎体验*
27 | > * 如果您使用iPv4地址,请确保域名的记录类型设置为**A**,如果是要使用iPv6,设置成**AAAA**
28 | > * 此脚本为DDNS实现的个人想法
29 |
30 | ## Restrict
31 | > 本脚本适用于家庭宽带IP为动态IP的情形,若不是,可以利用[frp](https://github.com/fatedier/frp)等NAT-DDNS内网穿透工具
32 | ## Configuration
33 | 本项目修改为使用配置文件方式存储用户配置,配置文件为JSON格式,存放于config.json文件中,形式如下:
34 | ```
35 | {
36 | "AccessKeyId": "Your_AccessKeyId",//你的阿里云AccessKeyId
37 | "AccessKeySecret": "Your_AccessKeySecret",//你的阿里云AccessKeySecret
38 | "First-level-domain": "Your_First-level-domain",//一级域名,例如 example.com
39 | "Second-level-domain": "Your_Second-level-domain"//二级域名,例如 ddns.example.com 填入ddns即可
40 | }
41 | ```
42 | ## Tip
43 | > 判断自家宽带是否是动态IP的方式:
44 | > * Step 1:百度搜索IP,查到自己的IP地址
45 | > * Step 2:接着本地开一个网站,比如在Windows下直接启动IIS,Linux下安装一个Apache或者Nginx启动,使用它们的默认页面
46 | > * Step 3:然后在路由器上设置好转发规则,公网IP的网络访问端口最好不要用80,80端口可能被运营商封了
47 | > * Step 4:最后利用前面查到的公网IP+端口号访问一下,看看能不能显示内网上的页面,如果可以,恭喜你!
48 | ## ScreenShots
49 |
50 | 注:因为我已经更新过了,所以它提示IP地址已存在,阿里云是不允许同一个IP重复更新的。第二张图为本地,第三张图为外网
51 | 
52 |
53 | 
54 |
55 | 
56 |
57 | ## Change Log
58 | > * 2018/5/29 网络连通性检测,只有在有网时才进行操作,否则等待网络连接
59 | > * 2018/6/10 启用配置文件存储用户数据
60 | > * 2018/9/24 修改失败提示输出,添加阿里帮助网址,让用户可查询错误对应信息
61 | > * 2018/12/24 改进ip获取方式,删除BS4依赖,感谢[@Nielamu](https://github.com/NieLamu)
62 | > * 2018/12/27 增加ipv6支持,感谢[@chnlkw](https://github.com/chnlkw)
63 | > * 2020/05/05 修改ipv4地址获取方式。如果失败,会写入日志,并在10秒后采用新的方式重试。感谢[@sunsheho](https://github.com/sunsheho)
64 |
65 | ## Contribution
66 | 如果感兴趣欢迎fork项目,如果有任何问题欢迎在issue区提问~
67 |
68 |
--------------------------------------------------------------------------------
/src/Utils.py:
--------------------------------------------------------------------------------
1 | '''
2 | 工具类
3 | Created By Martin Huang on 2018/5/19
4 | 修改记录:
5 | 2018/5/16 =》删除不需要的方法
6 | 2018/5/29 =》增加获取操作系统平台方法,增加网络连通性检测(后续考虑重构)
7 | 2018/6/3 =》网络连通性代码重构
8 | 2018/6/10 =》增加配置文件读取方法(可能有IO性能影响,考虑重构)
9 | '''
10 | import IpGetter
11 | import platform
12 | import subprocess
13 | import json
14 | from AcsClientSingleton import AcsClientSing
15 | from CommonRequestSingleton import CommonRequestSing
16 | class Utils:
17 |
18 | #获取真实公网IP
19 | def getRealIP():
20 | url = IpGetter.getIpPage();
21 | ip = IpGetter.getRealIp(url)
22 | return ip
23 |
24 | #获取真实公网IPv6
25 | def getRealIPv6():
26 | url = IpGetter.getIpPageV6();
27 | ip = IpGetter.getRealIpV6(url)
28 | return ip
29 |
30 | #获取二级域名的RecordId
31 | def getRecordId(domain):
32 | client = Utils.getAcsClient()
33 | request = Utils.getCommonRequest()
34 | request.set_domain('alidns.aliyuncs.com')
35 | request.set_version('2015-01-09')
36 | request.set_action_name('DescribeDomainRecords')
37 | request.add_query_param('DomainName', Utils.getConfigJson().get('First-level-domain'))
38 | response = client.do_action_with_exception(request)
39 | jsonObj = json.loads(response.decode("UTF-8"))
40 | records = jsonObj["DomainRecords"]["Record"]
41 | for each in records:
42 | if each["RR"] == domain:
43 | return each["RecordId"]
44 |
45 | #获取CommonRequest
46 | def getCommonRequest():
47 | return CommonRequestSing.getInstance()
48 |
49 | #获取AcsClient
50 | def getAcsClient():
51 | return AcsClientSing.getInstance()
52 |
53 | #获取操作系统平台
54 | def getOpeningSystem():
55 | return platform.system()
56 |
57 | #判断是否联网
58 | def isOnline():
59 | userOs = Utils.getOpeningSystem()
60 | try:
61 | if userOs == "Windows":
62 | subprocess.check_call(["ping", "-n", "2", "www.baidu.com"], stdout=subprocess.PIPE)
63 | else:
64 | subprocess.check_call(["ping", "-c", "2", "www.baidu.com"], stdout=subprocess.PIPE)
65 | return True
66 | except subprocess.CalledProcessError:
67 | print("网络未连通!请检查网络")
68 | return False
69 |
70 | #从config.json中获取配置信息JSON串
71 | def getConfigJson():
72 | with open('config.json') as file:
73 | jsonStr = json.loads(file.read())
74 | return jsonStr
75 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DDNS
2 | [中文](https://github.com/mgsky1/DDNS/blob/master/README_ZH_CN.md)|[English](https://github.com/mgsky1/DDNS/blob/master/README.md)
3 | ## Summary
4 | > Python and Aliyun SDK API have been used in this project. You can use this tool to map the local applications like NAS, DB, WEB etc to the internet.
5 | ## Install
6 | ```bash
7 | pip3 install aliyun-python-sdk-core-v3
8 | ```
9 | ## Run
10 | ```bash
11 | python3 src/DDNS.py # default ipv4
12 | python3 src/DDNS.py -6 # change to ipv6
13 | ```
14 | ## Note
15 | > * Based on Python3、Aliyun API.
16 | > * To begin, you can run the main function in DDNS.py. The main function in other .py files are for the test purpose.
17 | > * You can set this script as a timer task in your opening system. For example, running this script at 4:30am everyday or when connecting to the internet.
18 | > * On the [dev](https://github.com/mgsky1/DDNS/tree/dev) branch, this project supports binding multiple domains to the same ip address.
19 | > * If you use iPv4, please make sure that the record type of your domain which will be used is **A**. If you use iPv6, the type is **AAAA**.
20 | > * This script is my idea for implementing DDNS.
21 |
22 | ## Restrict
23 | > This script is suitable for the broadband which has a dynamic IP. If not, you can try NAT-DDNS tools like [frp](https://github.com/fatedier/frp).
24 |
25 | ## Configuration
26 | The config.json has some infomation you should provide. The config structure may like this:
27 | ```
28 | {
29 | "AccessKeyId": "Your_AccessKeyId",//Your Aliyun AccessKeyId
30 | "AccessKeySecret": "Your_AccessKeySecret",//Your Aliyun AccessKeySecret
31 | "First-level-domain": "Your_First-level-domain",//First level domain, eg example.com
32 | "Second-level-domain": "Your_Second-level-domain"//Second level domain, eg ddns.example.com Just input ddns
33 | }
34 | ```
35 | ## Tip
36 | > How to determine wether your broadband service has a dynamic IP.
37 | > * Step 1:Find your WAN IP by google or other tools.
38 | > * Step 2:Run a web service locally. For example, starting IIS in Windows or Apache in Linux and using their default webpage.
39 | > * Step 3: Set the map rules in your home router. The ports which you will use to access the local service over internet had better not to be 80 beacuse the 80 port may be blocked by your internet service provider.
40 | > * Step 4: Use the IP you fond by google and the port to access your local web service. If ok, congratulations!
41 |
42 | ## ScreenShots
43 | NOTE: Because I have updated before, the script tells me the DNS record has already exists. Aliyun does not allow users to update the same IP when the IP has not been changed. The second picture shows the local service. The Third one shows accessing local service over internet under the help of DDNS.
44 |
45 | 
46 |
47 | 
48 |
49 | 
50 |
51 | ## Change Log
52 | > * 2018/5/29 Add detecting internet access.
53 | > * 2018/6/10 Start using configuration file.
54 | > * 2018/9/24 Improve the error output
55 | > * 2018/12/24 Improve the way to get IP, deleteing BS4 dependence. Thanks [@Nielamu](https://github.com/NieLamu).
56 | > * 2018/12/27 Support ipv6. Thanks [@chnlkw](https://github.com/chnlkw).
57 | > * 2020/05/05 Improve the policy of getting ipv4 address. Once failed, it will write into the log and retry with new method after 10 sec. Thanks [@sunsheho](https://github.com/sunsheho).
58 |
59 | ## Contribution
60 | If you interest in this project and want to improve it, welcome to fork the project. Have any questions? you can ask in issue~
61 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/src/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
61 |
62 |
63 |
64 | Request
65 | CommonRequest
66 |
67 |
68 |
69 |