├── sync.log ├── requirements.txt ├── .gitmodules ├── README.md ├── .github └── workflows │ └── sync.yml ├── gen_csv.py └── LICENSE /sync.log: -------------------------------------------------------------------------------- 1 | 8c9a0ddbbc621b6ee025af350bea9bc5e4700b28 -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pandas~=1.3.4 2 | gitpython~=3.1.24 -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "MobileModels"] 2 | path = MobileModels 3 | url = https://github.com/KHwang9883/MobileModels.git 4 | branch = master -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MobileModels-csv 2 | 这是 https://github.com/KHwang9883/MobileModels 的 csv 格式版本,使用 GitHub Actions 自动生成并更新。 3 | 4 | ## gen_csv.py 脚本说明 5 | 这是用于将 markdown 格式的设备型号介绍转为 csv 格式的 python 脚本。 6 | 输出列:设备编号,设备类型,品牌代码,品牌名,型号编码,型号昵称,型号名称,版本名称 7 | 8 | **设备编号 (model)** 9 | 能从浏览器 UserAgent 中获取到的设备编号,如`华为 P40` 对应 `ANA-AL00` 10 | 一个 model 可能对应多个版本,也可能多个 model 对应一个版本。 11 | **设备类型 (device_type)** 12 | 包含:手机、手表、平板、电视、电视盒子、笔记本、pod 等 13 | 对应 csv 的值:mob,watch,pad,tv,tv_hub,computer,pod 14 | 会从一级标题、二级标题、加粗行中尝试提取。如果一级标题不存在则置为空,如果有多个二级标题,后面的二级标题(或加粗行)未检测到有效设备类型,会使用前面的设备类型。 15 | **品牌代码 (brand)** 16 | 从 brands 目录下的文件名中提取第一个单词 17 | **品牌名 (brand_title)** 18 | 从一级标题中按正则提取 19 | **型号编码 (code)** 20 | 从加粗行的前面中括号中提取 21 | **型号昵称 (code_alias)** 22 | 从加粗行的尾部小括号中提取 23 | **型号名称 (model_name)** 24 | 从加粗行去掉 code 和 code_alias 后剩余的内容 25 | **版本名称 (ver_name)** 26 | 从 model 行,提取冒号之后的内容,再去掉 model_name 的重合部分,只保留版本信息 27 | ~~有些版本名称可能没有完全包含 model_name,而是只包含其中一部分,还有些可能完全没包含model_name~~ 28 | ~~输出 ver_name 中,如果包含 model_name,然后去掉了一部分,则规定以"#"开头。~~ 29 | ~~如果有多个 model_name,且包含的不是第1个,则"#"前面会添加索引~~ 30 | ~~例如 `CPH2413` 对应 `一加 10T 印度版`,但所属的型号是 `一加 Ace Pro / 一加 10T`,有两个,和第二个型号相同,所以版本中去掉相同的 `一加 10T`部分,变成 `#印度版`,又因为对应的型号是第二个,索引是1,故最后是 `1#印度版`~~ 31 | 32 | ## 鸣谢 33 | - 感谢 [gen_psy.py](https://github.com/KHwang9883/MobileModels-csv/blob/main/gen_csv.py) 脚本作者 @anyongjin 34 | - 感谢 [jantacy/mobilemodels](https://github.com/jantacy/mobilemodels) 脚本作者 @jantacy @zhyi828 ,本项目使用了该 repo 部分代码 35 | -------------------------------------------------------------------------------- /.github/workflows/sync.yml: -------------------------------------------------------------------------------- 1 | name: Sync 2 | on: 3 | workflow_dispatch: # To allow manual runs 4 | schedule: 5 | - cron: '0 0 * * *' 6 | 7 | jobs: 8 | Task: 9 | runs-on: ubuntu-latest 10 | # if: github.event.repository.owner.id == github.event.sender.id # 自己点的 start 11 | steps: 12 | - name: Checkout repository and submodules 13 | uses: actions/checkout@v2 14 | with: 15 | submodules: true 16 | token: ${{ secrets.GITHUB_TOKEN }} 17 | - name: Git Submodule Update 18 | run: | 19 | git pull --recurse-submodules 20 | git submodule update --remote --recursive 21 | - name: Set up Python 3.8 22 | uses: actions/setup-python@v2 23 | with: 24 | python-version: 3.8 25 | - name: Install requirements 26 | run: | 27 | pip install -r requirements.txt 28 | - name: Update MobileModels 29 | run: | 30 | cd MobileModels 31 | ls 32 | git log 33 | echo "LATEST_COMMIT=$(git log -1 --format="%H")" >> $GITHUB_ENV 34 | cd .. 35 | - name: Run 36 | run: | 37 | echo `date +"%Y-%m-%d %H:%M:%S"` begin 38 | python gen_csv.py 39 | git status 40 | # git diff 41 | - name: Commit # 提交更新, fork后请自行修改user信息 42 | run: | 43 | git config --global user.email huangyf9883@gmail.com 44 | git config --global user.name Kevin Huang 45 | git add . 46 | git diff-index --quiet HEAD || git commit -m "Sync with MobileModels $LATEST_COMMIT" -a 47 | - name: Push changes 48 | uses: ad-m/github-push-action@master 49 | with: 50 | github_token: ${{ secrets.GITHUB_TOKEN }} # fork后自行配置GITHUB_TOKEN 51 | -------------------------------------------------------------------------------- /gen_csv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | # File : mo_models.py 4 | # Author: anyongjin 5 | # Date : 2022/11/12 6 | ''' 7 | 将设备型号从MarkDown读取为CSV格式的脚本 8 | 输出列:设备编号,设备类型,品牌代码,品牌名,型号编码,型号昵称,型号名称,版本名称 9 | ''' 10 | import os 11 | import re 12 | import traceback 13 | import pandas as pd 14 | from typing import Optional, List 15 | from os.path import dirname, abspath 16 | from git import Repo # rely on gitpython 17 | 18 | class PhoneModel: 19 | def __init__(self): 20 | """获取手机品牌型号""" 21 | # if origin == 0: # 拉取仓库 22 | # repo = Repo.clone_from(repo_address, repo_path) 23 | # else: # 拉取最新数据 24 | repo = Repo(repo_path) 25 | repo.remotes.origin.pull() 26 | self.new_commit = repo.head.commit.hexsha 27 | print("MobileModels latest commit: " + str(self.new_commit)) 28 | os.environ["LATEST_COMMIT"] = self.new_commit 29 | 30 | def data_save(self): 31 | # 保存新的commit值 32 | with open('sync.log', 'wt') as f: 33 | f.write(self.new_commit) 34 | 35 | repo_path = './MobileModels/' 36 | source_dir = os.path.join(repo_path, 'brands') 37 | 38 | device_type: Optional[str] = None # 设备类型:手机,电视,手环 39 | root_brand: Optional[str] = None # 品牌代码 40 | root_brand_title: Optional[str] = None # 品牌名 41 | devc_code: Optional[str] = None # 设备型号代码 42 | devc_code_alias: Optional[str] = None # 设备型号昵称 43 | devc_model_names: List[str] = [] # 设备型号正式名 44 | 45 | 46 | _re_title = re.compile(r'^#+') 47 | _re_blanks = re.compile(r'\s+') 48 | _re_char = re.compile(r'([+]+|[^\W_])') 49 | _re_word = re.compile(r'([a-zA-Z0-9]+|[^\W_]{,3})') 50 | _re_non_word = re.compile(r'[\W_]+') 51 | # 匹配model和版本的正则 52 | _re_model_ver = re.compile(r'^`(([^`]+)`\s*)+:\s*') 53 | _re_model_item = re.compile(r'`([^`]+)`') 54 | # 匹配设备类型的正则 55 | _re_device_type = re.compile(r'(手机|手表|手环|平板|电视主机|盒子|(智能)?电视|笔记本电脑|设备|穿戴|Mobile|Phone|Pad|Pod|Tablet|Watch|Band|WATCH|Device|\bTV\b|学习智慧屏|智慧屏)') 56 | _device_map = dict( 57 | 手机='mob', 58 | mobile='mob', 59 | phone='mob', 60 | 电视='tv', 61 | 智能电视='tv', 62 | 学习智慧屏='pad', 63 | 智慧屏='tv', 64 | 设备='device', 65 | 手表='watch', 66 | 手环='band', 67 | Band='band', 68 | 笔记本电脑='computer', 69 | tablet='pad', 70 | 平板='pad', 71 | 电视主机='tv_hub', 72 | 盒子='tv_hub' 73 | ) 74 | 75 | pd_cols = 'model,dtype,brand,brand_title,code,code_alias,model_name,ver_name'.split(',') 76 | pd_rows = [] 77 | 78 | 79 | def _process_h1(line: str): 80 | # 设置设备类型,品牌名 81 | global device_type, root_brand, root_brand_title 82 | assert root_brand, 'root_brand is required' 83 | # 替换无用描述词 84 | line = re.sub(r'(Global|早期|国行)', '', line) 85 | # 查找品牌结束位置 86 | end_pos, device_type = _read_device_type(line) 87 | brand_str = line[: end_pos] 88 | # 只获取长度不小于2的有效单词 89 | words = [mat.group() for mat in re.finditer(r'\w{2,}', brand_str) if len(mat.group()) >= 2] 90 | if not words: 91 | raise ValueError(f'no brand found in h1: {line}') 92 | if len(words) == 1: 93 | root_brand_title = words[0] 94 | return 95 | root_brand_title = root_brand 96 | for w in words: 97 | if root_brand.lower() == w.lower(): 98 | continue 99 | root_brand_title = w 100 | break 101 | 102 | 103 | def _read_device_type(line: str, raise_err: bool = True): 104 | type_mat = _re_device_type.search(line) 105 | if not type_mat: 106 | if raise_err: 107 | raise ValueError(f'unknown h1 format: {line}') 108 | else: 109 | return -1, None 110 | dtype = type_mat.group().lower() 111 | dtype = _device_map.get(dtype, dtype) 112 | return type_mat.start(), dtype 113 | 114 | 115 | def _process_bold_model(line: str): 116 | ''' 117 | 处理加粗的设备型号行 118 | :param line: 119 | :return: 120 | ''' 121 | global device_type, devc_code, devc_code_alias, devc_model_names 122 | _reset_context('code') 123 | code_mat = re.search(r'\[\`([^`]+)\`\]', line) 124 | code_nmat = re.search(r'\(\`([^`]+)\`\)', line) 125 | md_start, md_end = 0, len(line) 126 | if code_mat: 127 | devc_code = code_mat.group(1) 128 | md_start = code_mat.end() 129 | if code_nmat: 130 | devc_code_alias = code_nmat.group(1) 131 | md_end = code_nmat.start() 132 | model_name = _strip_text(line[md_start: md_end]) 133 | # 检查设备类型是否变化 134 | dtype = _read_device_type(model_name, False)[1] 135 | if dtype and dtype != device_type: 136 | device_type = dtype 137 | # 检查是否一行有多个品牌,以/分割 138 | model_names = _try_split_by_splash(model_name) 139 | model_names = [_strip_text(mname) for mname in model_names] 140 | # 检查是否包含品牌,包含则去除 141 | devc_model_names = [] 142 | for mname in model_names: 143 | brand_start = mname.find(root_brand) 144 | if brand_start >= 0: 145 | # 型号包含品牌名,去除 146 | mname = _strip_text(mname[brand_start + len(root_brand):]) 147 | dtype_mat = _re_device_type.search(mname) 148 | devc_model_names.append(mname) 149 | 150 | 151 | def _get_ver_name_with_model(ver_full: str, model_name: str): 152 | ''' 153 | 从最精细的版本中去除型号信息。可能不完全包含版本名称,而是包含版本的一部分 154 | :param ver_full: 155 | :param model_name: 156 | :return: 157 | ''' 158 | ver_words = _re_char.finditer(ver_full) 159 | model_first_word = _re_word.search(model_name).group().lower() 160 | ver_start = ver_full.lower().find(model_first_word) 161 | if ver_start < 0: 162 | return ver_full 163 | model_chars = [mat.group() for mat in _re_char.finditer(model_name)] 164 | model_idx = 0 165 | for ver_mat in ver_words: 166 | if ver_mat.start() < ver_start: 167 | continue 168 | if model_idx >= len(model_chars): 169 | return _strip_text(ver_full[ver_mat.start():]) 170 | ver_word = ver_mat.group() 171 | md_word = model_chars[model_idx] 172 | if ver_word.lower() == md_word.lower(): 173 | model_idx += 1 174 | continue 175 | clean_ver = _strip_text(ver_full[ver_mat.start():]) 176 | return clean_ver 177 | return '' 178 | 179 | 180 | def _strip_text(text: str): 181 | # 去除头部无效字符 182 | start = _re_char.search(text) 183 | if not start: 184 | return '' 185 | text = text[start.start():] 186 | # 去除尾部无效字符 187 | end_pos = len(text) - _re_char.search(text[::-1]).start() 188 | clean_text = text[:end_pos] 189 | # 补全缺失的括号 190 | brackets, prepend, appends = [], [], [] 191 | brac_map = {'(': ')', '(': ')', ')': '(', ')': '('} 192 | for c in clean_text: 193 | if c in {'(', '('}: 194 | btype = 1 195 | elif c in {')', ')'}: 196 | btype = 2 197 | else: 198 | continue 199 | if btype == 1: 200 | brackets.append(c) 201 | elif len(brackets) > 0: 202 | brackets.pop() 203 | else: 204 | prepend.append(brac_map[c]) 205 | for brac in brackets: 206 | appends.append(brac_map[brac]) 207 | return ''.join([*prepend, clean_text, *appends]) 208 | 209 | 210 | def _get_ver_name(ver_full: str): 211 | ver_names, last_err = [], None 212 | for i, mname in enumerate(devc_model_names): 213 | try: 214 | ver_names.append((i, _get_ver_name_with_model(ver_full, mname))) 215 | except ValueError as e: 216 | last_err = e 217 | if not ver_names: 218 | raise last_err 219 | ver_item = sorted(ver_names, key=lambda x: len(x[1]))[0] 220 | return ver_item[1] if not ver_item[0] else f'{ver_item[0]}{ver_item[1]}' 221 | 222 | def _try_split_by_splash(type_name: str): 223 | # 检查是否是/分割的多个版本。多个版本一般前几个单词相同(不区分大小写) 224 | ver_full_names = [vname.strip() for vname in type_name.split('/')] 225 | if len(ver_full_names) > 1: 226 | name1_arr = _re_non_word.split(ver_full_names[0]) 227 | name2_arr = _re_non_word.split(ver_full_names[1]) 228 | if name1_arr[0].lower() != name2_arr[0].lower(): 229 | # 首个单词不同(不区分大小写),不认为是多个版本 230 | return [type_name] 231 | return ver_full_names 232 | 233 | 234 | def _process_model_ver(line: str, mat: re.Match): 235 | global device_type, root_brand, root_brand_title, devc_code, devc_code_alias, devc_model_names 236 | model_text = mat.group() 237 | models = [m.group(1) for m in _re_model_item.finditer(model_text)] 238 | ver_full = _strip_text(line[mat.end():]) 239 | ver_full_names = _try_split_by_splash(ver_full) 240 | for full_name in ver_full_names: 241 | # 1. 找所有能作为前缀的 market name 242 | prefix_matches = [] 243 | for i, mname in enumerate(devc_model_names): 244 | if full_name.replace(' ', '').lower().startswith(mname.replace(' ', '').lower()): 245 | prefix_matches.append((i, len(mname.replace(' ', '')))) 246 | if prefix_matches: 247 | # 2. 选最长的 248 | matched_idx = max(prefix_matches, key=lambda x: x[1])[0] 249 | else: 250 | # 3. 兜底用最短匹配法 251 | best_idx = 0 252 | min_len = float('inf') 253 | for i, mname in enumerate(devc_model_names): 254 | try: 255 | v = _get_ver_name_with_model(full_name, mname) 256 | if len(v) < min_len: 257 | min_len = len(v) 258 | best_idx = i 259 | except Exception: 260 | continue 261 | matched_idx = best_idx 262 | mname = devc_model_names[matched_idx] 263 | ver_name = _get_ver_name_with_model(full_name, mname) 264 | for model in models: 265 | pd_rows.append((model, device_type, root_brand, root_brand_title, devc_code, devc_code_alias, 266 | mname, ver_name)) 267 | 268 | 269 | def _process_line(line: str): 270 | global device_type 271 | if line.startswith(('-', '>', '~')): 272 | return 273 | title_mat = _re_title.search(line) 274 | title_level = len(title_mat.group(0)) if title_mat else 0 275 | pure_line = line[title_level:].strip() 276 | if title_level == 1: 277 | _process_h1(pure_line) 278 | elif title_level == 2: 279 | dtype = _read_device_type(pure_line, False)[1] 280 | if dtype: 281 | device_type = dtype 282 | # 系列,子品牌,不同产品类型 283 | return 284 | elif title_level: 285 | raise ValueError(f'unknown title type: {title_level}, {line}') 286 | elif pure_line.startswith('**') and pure_line.endswith('**'): 287 | _process_bold_model(pure_line[2: -2]) 288 | elif detail_mat := _re_model_ver.search(pure_line): 289 | _process_model_ver(pure_line, detail_mat) 290 | else: 291 | raise ValueError(f'unknown line: {line}') 292 | 293 | 294 | def _reset_context(level: str): 295 | ''' 296 | 重置上下文: brand, code 297 | :param level: 298 | :return: 299 | ''' 300 | global device_type, root_brand_title, devc_code, devc_code_alias, devc_model_names 301 | if level == 'brand' or level == 'all': 302 | device_type = None 303 | root_brand_title = None 304 | if level == 'code' or level == 'all': 305 | devc_code = None 306 | devc_code_alias = None 307 | devc_model_names = [] 308 | 309 | 310 | def sync_brands(name: str): 311 | global root_brand 312 | _reset_context('all') 313 | root_brand = re.split(r'[\W_]+', name)[0].replace('shouji', '') 314 | full_path = os.path.join(source_dir, name) 315 | with open(full_path, 'r', encoding='utf-8') as fdata: 316 | for line in fdata: 317 | try: 318 | line = line.strip() 319 | if not line: 320 | continue 321 | _process_line(line) 322 | except Exception as e: 323 | print(f'exception process {root_brand}: {e}') 324 | traceback.print_exc() 325 | 326 | 327 | if __name__ == '__main__': 328 | fnames = sorted(os.listdir(source_dir)) 329 | for name in fnames: 330 | # if name.endswith('_en.md'): 331 | # continue 332 | print(f'process: {name}') 333 | sync_brands(name) 334 | df = pd.DataFrame(pd_rows, columns=pd_cols) 335 | 336 | # 新增:对 model_name 含斜杠且 ver_name 为空的行进行拆分 337 | new_rows = [] 338 | for row in df.itertuples(index=False, name=None): 339 | row = list(row) 340 | model_name, ver_name = row[6], row[7] 341 | if '/' in str(model_name) and (not ver_name or str(ver_name).strip() == ''): 342 | # 拆分 model_name 343 | for m in str(model_name).split('/'): 344 | new_row = row.copy() 345 | new_row[6] = m.strip() 346 | new_rows.append(tuple(new_row)) 347 | else: 348 | new_rows.append(tuple(row)) 349 | df = pd.DataFrame(new_rows, columns=pd_cols) 350 | df.to_csv('./models.csv', index=False, encoding='utf-8-sig') 351 | print('generate complete, out file: ./models.csv') 352 | 353 | try: 354 | with open('sync.log', 'rt') as f: 355 | last_commit = f.readline() 356 | except FileNotFoundError: 357 | last_commit = '' 358 | 359 | pm = PhoneModel() # 初始 pm=PhoneModel(0),后续更新可不填 360 | if pm.new_commit != last_commit: 361 | pm.data_save() 362 | else: 363 | print("No update, skip.") -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Attribution-NonCommercial-ShareAlike 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International 58 | Public License 59 | 60 | By exercising the Licensed Rights (defined below), You accept and agree 61 | to be bound by the terms and conditions of this Creative Commons 62 | Attribution-NonCommercial-ShareAlike 4.0 International Public License 63 | ("Public License"). To the extent this Public License may be 64 | interpreted as a contract, You are granted the Licensed Rights in 65 | consideration of Your acceptance of these terms and conditions, and the 66 | Licensor grants You such rights in consideration of benefits the 67 | Licensor receives from making the Licensed Material available under 68 | these terms and conditions. 69 | 70 | 71 | Section 1 -- Definitions. 72 | 73 | a. Adapted Material means material subject to Copyright and Similar 74 | Rights that is derived from or based upon the Licensed Material 75 | and in which the Licensed Material is translated, altered, 76 | arranged, transformed, or otherwise modified in a manner requiring 77 | permission under the Copyright and Similar Rights held by the 78 | Licensor. For purposes of this Public License, where the Licensed 79 | Material is a musical work, performance, or sound recording, 80 | Adapted Material is always produced where the Licensed Material is 81 | synched in timed relation with a moving image. 82 | 83 | b. Adapter's License means the license You apply to Your Copyright 84 | and Similar Rights in Your contributions to Adapted Material in 85 | accordance with the terms and conditions of this Public License. 86 | 87 | c. BY-NC-SA Compatible License means a license listed at 88 | creativecommons.org/compatiblelicenses, approved by Creative 89 | Commons as essentially the equivalent of this Public License. 90 | 91 | d. Copyright and Similar Rights means copyright and/or similar rights 92 | closely related to copyright including, without limitation, 93 | performance, broadcast, sound recording, and Sui Generis Database 94 | Rights, without regard to how the rights are labeled or 95 | categorized. For purposes of this Public License, the rights 96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 97 | Rights. 98 | 99 | e. Effective Technological Measures means those measures that, in the 100 | absence of proper authority, may not be circumvented under laws 101 | fulfilling obligations under Article 11 of the WIPO Copyright 102 | Treaty adopted on December 20, 1996, and/or similar international 103 | agreements. 104 | 105 | f. Exceptions and Limitations means fair use, fair dealing, and/or 106 | any other exception or limitation to Copyright and Similar Rights 107 | that applies to Your use of the Licensed Material. 108 | 109 | g. License Elements means the license attributes listed in the name 110 | of a Creative Commons Public License. The License Elements of this 111 | Public License are Attribution, NonCommercial, and ShareAlike. 112 | 113 | h. Licensed Material means the artistic or literary work, database, 114 | or other material to which the Licensor applied this Public 115 | License. 116 | 117 | i. Licensed Rights means the rights granted to You subject to the 118 | terms and conditions of this Public License, which are limited to 119 | all Copyright and Similar Rights that apply to Your use of the 120 | Licensed Material and that the Licensor has authority to license. 121 | 122 | j. Licensor means the individual(s) or entity(ies) granting rights 123 | under this Public License. 124 | 125 | k. NonCommercial means not primarily intended for or directed towards 126 | commercial advantage or monetary compensation. For purposes of 127 | this Public License, the exchange of the Licensed Material for 128 | other material subject to Copyright and Similar Rights by digital 129 | file-sharing or similar means is NonCommercial provided there is 130 | no payment of monetary compensation in connection with the 131 | exchange. 132 | 133 | l. Share means to provide material to the public by any means or 134 | process that requires permission under the Licensed Rights, such 135 | as reproduction, public display, public performance, distribution, 136 | dissemination, communication, or importation, and to make material 137 | available to the public including in ways that members of the 138 | public may access the material from a place and at a time 139 | individually chosen by them. 140 | 141 | m. Sui Generis Database Rights means rights other than copyright 142 | resulting from Directive 96/9/EC of the European Parliament and of 143 | the Council of 11 March 1996 on the legal protection of databases, 144 | as amended and/or succeeded, as well as other essentially 145 | equivalent rights anywhere in the world. 146 | 147 | n. You means the individual or entity exercising the Licensed Rights 148 | under this Public License. Your has a corresponding meaning. 149 | 150 | 151 | Section 2 -- Scope. 152 | 153 | a. License grant. 154 | 155 | 1. Subject to the terms and conditions of this Public License, 156 | the Licensor hereby grants You a worldwide, royalty-free, 157 | non-sublicensable, non-exclusive, irrevocable license to 158 | exercise the Licensed Rights in the Licensed Material to: 159 | 160 | a. reproduce and Share the Licensed Material, in whole or 161 | in part, for NonCommercial purposes only; and 162 | 163 | b. produce, reproduce, and Share Adapted Material for 164 | NonCommercial purposes only. 165 | 166 | 2. Exceptions and Limitations. For the avoidance of doubt, where 167 | Exceptions and Limitations apply to Your use, this Public 168 | License does not apply, and You do not need to comply with 169 | its terms and conditions. 170 | 171 | 3. Term. The term of this Public License is specified in Section 172 | 6(a). 173 | 174 | 4. Media and formats; technical modifications allowed. The 175 | Licensor authorizes You to exercise the Licensed Rights in 176 | all media and formats whether now known or hereafter created, 177 | and to make technical modifications necessary to do so. The 178 | Licensor waives and/or agrees not to assert any right or 179 | authority to forbid You from making technical modifications 180 | necessary to exercise the Licensed Rights, including 181 | technical modifications necessary to circumvent Effective 182 | Technological Measures. For purposes of this Public License, 183 | simply making modifications authorized by this Section 2(a) 184 | (4) never produces Adapted Material. 185 | 186 | 5. Downstream recipients. 187 | 188 | a. Offer from the Licensor -- Licensed Material. Every 189 | recipient of the Licensed Material automatically 190 | receives an offer from the Licensor to exercise the 191 | Licensed Rights under the terms and conditions of this 192 | Public License. 193 | 194 | b. Additional offer from the Licensor -- Adapted Material. 195 | Every recipient of Adapted Material from You 196 | automatically receives an offer from the Licensor to 197 | exercise the Licensed Rights in the Adapted Material 198 | under the conditions of the Adapter's License You apply. 199 | 200 | c. No downstream restrictions. You may not offer or impose 201 | any additional or different terms or conditions on, or 202 | apply any Effective Technological Measures to, the 203 | Licensed Material if doing so restricts exercise of the 204 | Licensed Rights by any recipient of the Licensed 205 | Material. 206 | 207 | 6. No endorsement. Nothing in this Public License constitutes or 208 | may be construed as permission to assert or imply that You 209 | are, or that Your use of the Licensed Material is, connected 210 | with, or sponsored, endorsed, or granted official status by, 211 | the Licensor or others designated to receive attribution as 212 | provided in Section 3(a)(1)(A)(i). 213 | 214 | b. Other rights. 215 | 216 | 1. Moral rights, such as the right of integrity, are not 217 | licensed under this Public License, nor are publicity, 218 | privacy, and/or other similar personality rights; however, to 219 | the extent possible, the Licensor waives and/or agrees not to 220 | assert any such rights held by the Licensor to the limited 221 | extent necessary to allow You to exercise the Licensed 222 | Rights, but not otherwise. 223 | 224 | 2. Patent and trademark rights are not licensed under this 225 | Public License. 226 | 227 | 3. To the extent possible, the Licensor waives any right to 228 | collect royalties from You for the exercise of the Licensed 229 | Rights, whether directly or through a collecting society 230 | under any voluntary or waivable statutory or compulsory 231 | licensing scheme. In all other cases the Licensor expressly 232 | reserves any right to collect such royalties, including when 233 | the Licensed Material is used other than for NonCommercial 234 | purposes. 235 | 236 | 237 | Section 3 -- License Conditions. 238 | 239 | Your exercise of the Licensed Rights is expressly made subject to the 240 | following conditions. 241 | 242 | a. Attribution. 243 | 244 | 1. If You Share the Licensed Material (including in modified 245 | form), You must: 246 | 247 | a. retain the following if it is supplied by the Licensor 248 | with the Licensed Material: 249 | 250 | i. identification of the creator(s) of the Licensed 251 | Material and any others designated to receive 252 | attribution, in any reasonable manner requested by 253 | the Licensor (including by pseudonym if 254 | designated); 255 | 256 | ii. a copyright notice; 257 | 258 | iii. a notice that refers to this Public License; 259 | 260 | iv. a notice that refers to the disclaimer of 261 | warranties; 262 | 263 | v. a URI or hyperlink to the Licensed Material to the 264 | extent reasonably practicable; 265 | 266 | b. indicate if You modified the Licensed Material and 267 | retain an indication of any previous modifications; and 268 | 269 | c. indicate the Licensed Material is licensed under this 270 | Public License, and include the text of, or the URI or 271 | hyperlink to, this Public License. 272 | 273 | 2. You may satisfy the conditions in Section 3(a)(1) in any 274 | reasonable manner based on the medium, means, and context in 275 | which You Share the Licensed Material. For example, it may be 276 | reasonable to satisfy the conditions by providing a URI or 277 | hyperlink to a resource that includes the required 278 | information. 279 | 3. If requested by the Licensor, You must remove any of the 280 | information required by Section 3(a)(1)(A) to the extent 281 | reasonably practicable. 282 | 283 | b. ShareAlike. 284 | 285 | In addition to the conditions in Section 3(a), if You Share 286 | Adapted Material You produce, the following conditions also apply. 287 | 288 | 1. The Adapter's License You apply must be a Creative Commons 289 | license with the same License Elements, this version or 290 | later, or a BY-NC-SA Compatible License. 291 | 292 | 2. You must include the text of, or the URI or hyperlink to, the 293 | Adapter's License You apply. You may satisfy this condition 294 | in any reasonable manner based on the medium, means, and 295 | context in which You Share Adapted Material. 296 | 297 | 3. You may not offer or impose any additional or different terms 298 | or conditions on, or apply any Effective Technological 299 | Measures to, Adapted Material that restrict exercise of the 300 | rights granted under the Adapter's License You apply. 301 | 302 | 303 | Section 4 -- Sui Generis Database Rights. 304 | 305 | Where the Licensed Rights include Sui Generis Database Rights that 306 | apply to Your use of the Licensed Material: 307 | 308 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 309 | to extract, reuse, reproduce, and Share all or a substantial 310 | portion of the contents of the database for NonCommercial purposes 311 | only; 312 | 313 | b. if You include all or a substantial portion of the database 314 | contents in a database in which You have Sui Generis Database 315 | Rights, then the database in which You have Sui Generis Database 316 | Rights (but not its individual contents) is Adapted Material, 317 | including for purposes of Section 3(b); and 318 | 319 | c. You must comply with the conditions in Section 3(a) if You Share 320 | all or a substantial portion of the contents of the database. 321 | 322 | For the avoidance of doubt, this Section 4 supplements and does not 323 | replace Your obligations under this Public License where the Licensed 324 | Rights include other Copyright and Similar Rights. 325 | 326 | 327 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 328 | 329 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 330 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 331 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 332 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 333 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 334 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 335 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 336 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 337 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 338 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 339 | 340 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 341 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 342 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 343 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 344 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 345 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 346 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 347 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 348 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 349 | 350 | c. The disclaimer of warranties and limitation of liability provided 351 | above shall be interpreted in a manner that, to the extent 352 | possible, most closely approximates an absolute disclaimer and 353 | waiver of all liability. 354 | 355 | 356 | Section 6 -- Term and Termination. 357 | 358 | a. This Public License applies for the term of the Copyright and 359 | Similar Rights licensed here. However, if You fail to comply with 360 | this Public License, then Your rights under this Public License 361 | terminate automatically. 362 | 363 | b. Where Your right to use the Licensed Material has terminated under 364 | Section 6(a), it reinstates: 365 | 366 | 1. automatically as of the date the violation is cured, provided 367 | it is cured within 30 days of Your discovery of the 368 | violation; or 369 | 370 | 2. upon express reinstatement by the Licensor. 371 | 372 | For the avoidance of doubt, this Section 6(b) does not affect any 373 | right the Licensor may have to seek remedies for Your violations 374 | of this Public License. 375 | 376 | c. For the avoidance of doubt, the Licensor may also offer the 377 | Licensed Material under separate terms or conditions or stop 378 | distributing the Licensed Material at any time; however, doing so 379 | will not terminate this Public License. 380 | 381 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 382 | License. 383 | 384 | 385 | Section 7 -- Other Terms and Conditions. 386 | 387 | a. The Licensor shall not be bound by any additional or different 388 | terms or conditions communicated by You unless expressly agreed. 389 | 390 | b. Any arrangements, understandings, or agreements regarding the 391 | Licensed Material not stated herein are separate from and 392 | independent of the terms and conditions of this Public License. 393 | 394 | 395 | Section 8 -- Interpretation. 396 | 397 | a. For the avoidance of doubt, this Public License does not, and 398 | shall not be interpreted to, reduce, limit, restrict, or impose 399 | conditions on any use of the Licensed Material that could lawfully 400 | be made without permission under this Public License. 401 | 402 | b. To the extent possible, if any provision of this Public License is 403 | deemed unenforceable, it shall be automatically reformed to the 404 | minimum extent necessary to make it enforceable. If the provision 405 | cannot be reformed, it shall be severed from this Public License 406 | without affecting the enforceability of the remaining terms and 407 | conditions. 408 | 409 | c. No term or condition of this Public License will be waived and no 410 | failure to comply consented to unless expressly agreed to by the 411 | Licensor. 412 | 413 | d. Nothing in this Public License constitutes or may be interpreted 414 | as a limitation upon, or waiver of, any privileges and immunities 415 | that apply to the Licensor or You, including from the legal 416 | processes of any jurisdiction or authority. 417 | 418 | ======================================================================= 419 | 420 | Creative Commons is not a party to its public 421 | licenses. Notwithstanding, Creative Commons may elect to apply one of 422 | its public licenses to material it publishes and in those instances 423 | will be considered the “Licensor.” The text of the Creative Commons 424 | public licenses is dedicated to the public domain under the CC0 Public 425 | Domain Dedication. Except for the limited purpose of indicating that 426 | material is shared under a Creative Commons public license or as 427 | otherwise permitted by the Creative Commons policies published at 428 | creativecommons.org/policies, Creative Commons does not authorize the 429 | use of the trademark "Creative Commons" or any other trademark or logo 430 | of Creative Commons without its prior written consent including, 431 | without limitation, in connection with any unauthorized modifications 432 | to any of its public licenses or any other arrangements, 433 | understandings, or agreements concerning use of licensed material. For 434 | the avoidance of doubt, this paragraph does not form part of the 435 | public licenses. 436 | 437 | Creative Commons may be contacted at creativecommons.org. --------------------------------------------------------------------------------