diff --git a/DB/redis_session.py b/DB/redis_session.py new file mode 100644 index 0000000..5941c15 --- /dev/null +++ b/DB/redis_session.py @@ -0,0 +1,14 @@ +# coding: utf-8 +# Create by Annhuny On 2020-01-07 01:42 +# File Name : redis_session.py +import redis + +from config import conf + + +redis_cfg = conf.get('DB').get('redis') +r_session = redis.Redis(**{ + 'host': redis_cfg.get('host'), + 'port': redis_cfg.get('port'), + 'password': redis_cfg.get('password') +}) diff --git a/DB/service.py b/DB/service.py index 6cf9eb1..87a2a37 100644 --- a/DB/service.py +++ b/DB/service.py @@ -2,9 +2,36 @@ # Create by Annhuny On 2019-12-28 01:58 # File Name : service.py from DB.sqlalchemy_session import session +from Models.models import SeasonStatistic, Season, DailyStatistic -def get_season_statistic_by_season_id(season_id, order_by): - session.query() +# season +from utils.tools import default_datetime_format +def get_season_list(): + return session.query(Season).all() + + +def get_season_by_id(season_id): + return session.query(Season).filter_by(id=season_id).first() + + +def get_season_statistic_by_season_id(season_id): + return session.query(SeasonStatistic).filter_by(seasonId=season_id).all() + + +# daily +def get_daily_statistic_by_player_tag_and_datetime_tag_list(player_tag, datetime_tag_list): + datetime_tag_list = [item.strftime(default_datetime_format) for item in datetime_tag_list] + return session.query(DailyStatistic)\ + .filter_by(tag=player_tag)\ + .filter(DailyStatistic.datetimeTag.in_(datetime_tag_list)) \ + .order_by(DailyStatistic.id.asc()) \ + .all() + + +def get_daily_statistic_by_datetime_tag(datetime_tag): + return session.query(DailyStatistic)\ + .filter_by(datetimeTag=datetime_tag)\ + .all() diff --git a/DB/sqlalchemy_session.py b/DB/sqlalchemy_session.py index 22900a9..3c43ede 100644 --- a/DB/sqlalchemy_session.py +++ b/DB/sqlalchemy_session.py @@ -9,9 +9,13 @@ from config import conf +def to_dict(self): + return {c.name: getattr(self, c.name, None) for c in self.__table__.columns} + + Base = declarative_base() +Base.to_dict = to_dict -# 初始化数据库连接 db_conf = conf.get('DB').get('mysql') engine = create_engine('mysql+mysqlconnector://{user}:{password}@{ip}:{port}/{database}'.format(**{ 'user': db_conf.get('user'), @@ -19,8 +23,8 @@ 'ip': db_conf.get('ip'), 'port': db_conf.get('port'), 'database': db_conf.get('database'), -})) +}), pool_size=5, max_overflow=10, pool_timeout=30, pool_pre_ping=True) # 创建DBSession类型: DBSession = sessionmaker(bind=engine) -session = DBSession() +session = DBSession(expire_on_commit=False) diff --git a/Models/enums.py b/Models/enums.py new file mode 100644 index 0000000..203bf97 --- /dev/null +++ b/Models/enums.py @@ -0,0 +1,22 @@ +# coding: utf-8 +# Create by Annhuny On 2019-12-28 19:16 +# File Name : enums.py +from enum import Enum + + +class ErrEnums(Enum): + TestError = (200, 'test') + DatetimeParamsError = (101, '开始时间晚于结束时间') + IntervalStepError = (102, '由于时间采集粒度为2小时,间隔必须为2的整数倍') + DatetimeIntervalError = (103, '间隔过多,最大行数24') + + +class SeasonStatus(object): + INACTIVE = 0 + ACTIVE = 1 + + +class IntervalType(object): + HOURS = 1 + DAY = 2 + MONTH = 3 diff --git a/Models/models.py b/Models/models.py index 60d7bd7..f99989f 100644 --- a/Models/models.py +++ b/Models/models.py @@ -1,15 +1,26 @@ #!/usr/bin/env python # Create by Annhuny On 2019-12-25 20:04 # File Name : Members.py -from sqlalchemy import Column, String, Integer, JSON, DateTime +from sqlalchemy import Column, String, Integer, JSON, DateTime, func from DB.sqlalchemy_session import Base -class Member(Base): - __tablename__ = 'members' +class Season(Base): + __tablename__ = 'season' id = Column(Integer, primary_key=True) + name = Column(String) + status = Column(Integer) + createAt = Column(DateTime, server_default=func.now()) + updateAt = Column(DateTime, server_default=func.now()) + + +class SeasonStatistic(Base): + __tablename__ = 'season_statistic' + + id = Column(Integer, primary_key=True) + seasonId = Column(Integer) tag = Column(String) name = Column(String) role = Column(String) @@ -19,16 +30,21 @@ class Member(Base): versusTrophies = Column(Integer) clanRank = Column(Integer) previousClanRank = Column(Integer) + attackWins = Column(Integer) donations = Column(Integer) donationsReceived = Column(Integer) + createAt = Column(DateTime, server_default=func.now()) + updateAt = Column(DateTime, server_default=func.now()) -class FlowingData(Base): - __tablename__ = 'flowing_data' +class DailyStatistic(Base): + __tablename__ = 'daily_statistic' id = Column(Integer, primary_key=True) tag = Column(String) + name = Column(String) expLevel = Column(Integer) + townHallLevel = Column(Integer) trophies = Column(Integer) versusTrophies = Column(Integer) attackWins = Column(Integer) @@ -38,8 +54,6 @@ class FlowingData(Base): elixir = Column(Integer) darkElixir = Column(Integer) datetimeTag = Column(DateTime) - - - - + createAt = Column(DateTime, server_default=func.now()) + updateAt = Column(DateTime, server_default=func.now()) diff --git a/README.md b/README.md new file mode 100644 index 0000000..681c095 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +手游部落冲突 + +- 折线图 +- 赛季统计 + +让我看看是哪些伸手党整天白嫖 + +![demo](./demo.png) \ No newline at end of file diff --git a/asgi.py b/asgi.py index 8859949..f29cb32 100644 --- a/asgi.py +++ b/asgi.py @@ -11,6 +11,6 @@ from django.core.asgi import get_asgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'coc.settings') +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings') application = get_asgi_application() diff --git a/config.py b/config.py index 1a506e4..1c39d97 100644 --- a/config.py +++ b/config.py @@ -1,3 +1,4 @@ +# coding: utf-8 #!/usr/bin/env python # Create by Annhuny On 2019-12-27 16:17 # File Name : config.py @@ -7,7 +8,8 @@ import yaml -from settings import PROJECT_ROOT_DIR, CFG_FILE_NAME +PROJECT_ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) +CFG_FILE_NAME = 'config.yml' class ConfSingleton(object): diff --git a/demo.png b/demo.png new file mode 100644 index 0000000..2b52b72 Binary files /dev/null and b/demo.png differ diff --git a/errors.py b/errors.py index cc69ec6..f946cc7 100644 --- a/errors.py +++ b/errors.py @@ -4,4 +4,12 @@ class CustomError(Exception): - pass \ No newline at end of file + def __init__(self, err): + self.code = err.value[0] + self.msg = err.value[1] + + def __str__(self): + return 'code: {}, msg:{}'.format(self.code, self.msg) + + +DEFAULT_ERR_CODE = -1 diff --git a/initdb.sql b/initdb.sql index 993e830..1e0ba3e 100644 --- a/initdb.sql +++ b/initdb.sql @@ -1,47 +1,54 @@ -create table if not exists `season_statistic` ( - `id` varchar (15) not null default '' primary key, - `seasonId` integer not null default 0, - `tag` varchar (64) not null default '', - `name` varchar (64) not null default '', - `role` varchar (16) not null default '', - `expLevel` integer unsigned not null default 0, - `league` varchar (4048) not null default '', - `trophies` integer unsigned not null default 0, - `versusTrophies` integer unsigned not null default 0, - `clanRank` integer unsigned not null default 0, - `previousClanRank` integer unsigned not null default 0, - `attackWins` integer unsigned not null default 0, - `donations` integer unsigned not null default 0, - `donationsReceived` integer unsigned not null default 0, - key `idx_seasonId` (`seasonId`) -) engine=innodb default charset=utf8; +CREATE TABLE `season_statistic` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `seasonId` int(11) NOT NULL DEFAULT '0', + `tag` varchar(64) NOT NULL DEFAULT '', + `name` varchar(64) NOT NULL DEFAULT '', + `role` varchar(16) NOT NULL DEFAULT '', + `expLevel` int(10) unsigned NOT NULL DEFAULT '0', + `league` varchar(4048) NOT NULL DEFAULT '{}', + `trophies` int(10) unsigned NOT NULL DEFAULT '0', + `versusTrophies` int(10) unsigned NOT NULL DEFAULT '0', + `clanRank` int(10) unsigned NOT NULL DEFAULT '0', + `previousClanRank` int(10) unsigned NOT NULL DEFAULT '0', + `attackWins` int(10) NOT NULL DEFAULT '0', + `donations` int(10) unsigned NOT NULL DEFAULT '0', + `donationsReceived` int(10) unsigned NOT NULL DEFAULT '0', + `createAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updateAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `idx_seasonId` (`seasonId`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -create table if not exists `season` ( - `id` varchar (15) not null default '' primary key, - `name` varchar (255) not null default '' unique key, - `status` integer not null default 0, - `createAt` datetime not null default current_timestamp, - `updateAt` datetime not null default current_timestamp on update current_timestamp, - unique key `unq_name` (`name`) -) engine=innodb default charset=utf8; +CREATE TABLE `season` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL DEFAULT '', + `status` int(11) NOT NULL DEFAULT '0', + `createAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updateAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`), + UNIQUE KEY `unq_name` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -create table if not exists `flowing_data` ( - `id` integer auto_increment primary key, - `tag` varchar (15) not null default '', - `expLevel` integer unsigned not null default 0, - `trophies` integer unsigned not null default 0, - `versusTrophies` integer unsigned not null default 0, - `attackWins` integer unsigned not null default 0, - `donations` integer unsigned not null default 0, - `donationsReceived` integer unsigned not null default 0, - `gold` integer unsigned not null default 0, - `elixir` integer unsigned not null default 0, - `darkElixir` integer unsigned not null default 0, - `dateTimeTag` datetime not null default current_timestamp, - `createAt` datetime not null default current_timestamp, - `updateAt` datetime not null default current_timestamp on update current_timestamp, - key `idx_dateTimeTag` (`dateTimeTag`), - key `idx_tag` (`tag`) -) engine=innodb default charset=utf8; +CREATE TABLE `daily_statistic` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `tag` varchar(15) NOT NULL DEFAULT '', + `name` varchar(64) NOT NULL DEFAULT '', + `expLevel` int(10) unsigned NOT NULL DEFAULT '0', + `trophies` int(10) unsigned NOT NULL DEFAULT '0', + `versusTrophies` int(10) unsigned NOT NULL DEFAULT '0', + `attackWins` int(10) unsigned NOT NULL DEFAULT '0', + `donations` int(10) unsigned NOT NULL DEFAULT '0', + `donationsReceived` int(10) unsigned NOT NULL DEFAULT '0', + `gold` int(10) unsigned NOT NULL DEFAULT '0', + `elixir` int(10) unsigned NOT NULL DEFAULT '0', + `darkElixir` int(10) unsigned NOT NULL DEFAULT '0', + `dateTimeTag` datetime NOT NULL, + `createAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updateAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `idx_dateTimeTag` (`dateTimeTag`), + KEY `idx_tag` (`tag`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/json_example/clan_detail.json b/json_example/clan_detail.json new file mode 100644 index 0000000..62be537 --- /dev/null +++ b/json_example/clan_detail.json @@ -0,0 +1,864 @@ +{ + "tag": "#PCCR9LQU", + "name": "风月阁", + "type": "inviteOnly", + "description": "①和谐 有爱 互助 超越🇨🇳\n②参战成员灵活切换作战状态(换牌子)🍎🍏\n③劳者多得,不服来辩😎\n④速本、伸手党绕路👊👊 \n⑤Q群335672475 Vx找首领 不加不留✈️", + "location": { + "id": 32000056, + "name": "China", + "isCountry": true, + "countryCode": "CN" + }, + "badgeUrls": { + "small": "https://api-assets.clashofclans.com/badges/70/IQ1xLl2Jqa-eCIy-MLH9G8RcI1UFNTnoJ28YoQRNqlY.png", + "large": "https://api-assets.clashofclans.com/badges/512/IQ1xLl2Jqa-eCIy-MLH9G8RcI1UFNTnoJ28YoQRNqlY.png", + "medium": "https://api-assets.clashofclans.com/badges/200/IQ1xLl2Jqa-eCIy-MLH9G8RcI1UFNTnoJ28YoQRNqlY.png" + }, + "clanLevel": 12, + "clanPoints": 25966, + "clanVersusPoints": 25059, + "requiredTrophies": 1700, + "warFrequency": "always", + "warWinStreak": 2, + "warWins": 295, + "isWarLogPublic": false, + "members": 50, + "memberList": [ + { + "tag": "#8JG09J8PR", + "name": "你不懂我的基地", + "role": "member", + "expLevel": 145, + "league": { + "id": 29000017, + "name": "Champion League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/kLWSSyq7vJiRiCantiKCoFuSJOxief6R1ky6AyfB8q0.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/kLWSSyq7vJiRiCantiKCoFuSJOxief6R1ky6AyfB8q0.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/kLWSSyq7vJiRiCantiKCoFuSJOxief6R1ky6AyfB8q0.png" + } + }, + "trophies": 3641, + "versusTrophies": 2884, + "clanRank": 1, + "previousClanRank": 1, + "donations": 2017, + "donationsReceived": 1226 + }, + { + "tag": "#8QVPRY0C0", + "name": "谁知道", + "role": "admin", + "expLevel": 121, + "league": { + "id": 29000016, + "name": "Champion League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/JmmTbspV86xBigM7OP5_SjsEDPuE7oXjZC9aOy8xO3s.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/JmmTbspV86xBigM7OP5_SjsEDPuE7oXjZC9aOy8xO3s.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/JmmTbspV86xBigM7OP5_SjsEDPuE7oXjZC9aOy8xO3s.png" + } + }, + "trophies": 3179, + "versusTrophies": 2597, + "clanRank": 2, + "previousClanRank": 3, + "donations": 3734, + "donationsReceived": 988 + }, + { + "tag": "#YV2UL0RJ2", + "name": "雪月风花", + "role": "member", + "expLevel": 118, + "league": { + "id": 29000015, + "name": "Master League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png" + } + }, + "trophies": 3112, + "versusTrophies": 2328, + "clanRank": 3, + "previousClanRank": 4, + "donations": 111, + "donationsReceived": 370 + }, + { + "tag": "#LUCQPLJR", + "name": "妈妈说吃☞腊☜条越多人就越帅^", + "role": "coLeader", + "expLevel": 169, + "league": { + "id": 29000015, + "name": "Master League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png" + } + }, + "trophies": 3055, + "versusTrophies": 2474, + "clanRank": 4, + "previousClanRank": 5, + "donations": 6154, + "donationsReceived": 1482 + }, + { + "tag": "#YJ8902C0", + "name": "采蘑菇的小姑娘", + "role": "coLeader", + "expLevel": 118, + "league": { + "id": 29000015, + "name": "Master League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png" + } + }, + "trophies": 2995, + "versusTrophies": 1851, + "clanRank": 5, + "previousClanRank": 6, + "donations": 354, + "donationsReceived": 761 + }, + { + "tag": "#89Y0PLUV8", + "name": "二宝", + "role": "coLeader", + "expLevel": 201, + "league": { + "id": 29000014, + "name": "Master League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png" + } + }, + "trophies": 2943, + "versusTrophies": 3983, + "clanRank": 6, + "previousClanRank": 2, + "donations": 2337, + "donationsReceived": 3064 + }, + { + "tag": "#22GU0VCQR", + "name": "annhuny", + "role": "coLeader", + "expLevel": 145, + "league": { + "id": 29000014, + "name": "Master League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png" + } + }, + "trophies": 2911, + "versusTrophies": 2538, + "clanRank": 7, + "previousClanRank": 7, + "donations": 1486, + "donationsReceived": 406 + }, + { + "tag": "#R09J2QQP", + "name": "小明", + "role": "coLeader", + "expLevel": 130, + "league": { + "id": 29000013, + "name": "Master League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png" + } + }, + "trophies": 2747, + "versusTrophies": 1868, + "clanRank": 8, + "previousClanRank": 8, + "donations": 211, + "donationsReceived": 605 + }, + { + "tag": "#9UPJQL20U", + "name": "龚先生ڞ贼帅", + "role": "member", + "expLevel": 97, + "league": { + "id": 29000013, + "name": "Master League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png" + } + }, + "trophies": 2731, + "versusTrophies": 2137, + "clanRank": 9, + "previousClanRank": 9, + "donations": 723, + "donationsReceived": 801 + }, + { + "tag": "#LP2Y8C9LL", + "name": "愿念似风", + "role": "member", + "expLevel": 97, + "league": { + "id": 29000013, + "name": "Master League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png" + } + }, + "trophies": 2689, + "versusTrophies": 2393, + "clanRank": 10, + "previousClanRank": 11, + "donations": 1469, + "donationsReceived": 271 + }, + { + "tag": "#YPURU9VYL", + "name": "blk", + "role": "coLeader", + "expLevel": 118, + "league": { + "id": 29000013, + "name": "Master League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png" + } + }, + "trophies": 2649, + "versusTrophies": 2109, + "clanRank": 11, + "previousClanRank": 10, + "donations": 132, + "donationsReceived": 271 + }, + { + "tag": "#YU2RPYCJ", + "name": "噬魂", + "role": "member", + "expLevel": 138, + "league": { + "id": 29000000, + "name": "Unranked", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png" + } + }, + "trophies": 2580, + "versusTrophies": 2757, + "clanRank": 12, + "previousClanRank": 12, + "donations": 0, + "donationsReceived": 0 + }, + { + "tag": "#P0LQV9UL9", + "name": "虎牙搜弑戥", + "role": "member", + "expLevel": 115, + "league": { + "id": 29000012, + "name": "Crystal League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png" + } + }, + "trophies": 2526, + "versusTrophies": 2713, + "clanRank": 13, + "previousClanRank": 13, + "donations": 178, + "donationsReceived": 364 + }, + { + "tag": "#2PQV92QUJ", + "name": "芋芋芋芋圆", + "role": "coLeader", + "expLevel": 182, + "league": { + "id": 29000012, + "name": "Crystal League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png" + } + }, + "trophies": 2437, + "versusTrophies": 3302, + "clanRank": 14, + "previousClanRank": 17, + "donations": 3235, + "donationsReceived": 476 + }, + { + "tag": "#8J0JPGPGP", + "name": "诛仙家的小仙女", + "role": "member", + "expLevel": 112, + "league": { + "id": 29000012, + "name": "Crystal League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png" + } + }, + "trophies": 2434, + "versusTrophies": 2676, + "clanRank": 15, + "previousClanRank": 15, + "donations": 41, + "donationsReceived": 661 + }, + { + "tag": "#9VLGPCYYQ", + "name": "好好孑孓", + "role": "admin", + "expLevel": 136, + "league": { + "id": 29000012, + "name": "Crystal League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png" + } + }, + "trophies": 2433, + "versusTrophies": 2521, + "clanRank": 16, + "previousClanRank": 14, + "donations": 2356, + "donationsReceived": 709 + }, + { + "tag": "#PGY8RJGQ0", + "name": "Queen丶乱世倾城", + "role": "member", + "expLevel": 106, + "league": { + "id": 29000012, + "name": "Crystal League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png" + } + }, + "trophies": 2400, + "versusTrophies": 2358, + "clanRank": 17, + "previousClanRank": 16, + "donations": 317, + "donationsReceived": 101 + }, + { + "tag": "#YUYJRQUJ2", + "name": "人生有梦,各自精彩", + "role": "admin", + "expLevel": 117, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2378, + "versusTrophies": 2331, + "clanRank": 18, + "previousClanRank": 19, + "donations": 66, + "donationsReceived": 11059 + }, + { + "tag": "#998PLGCR", + "name": "流星", + "role": "member", + "expLevel": 126, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2350, + "versusTrophies": 1278, + "clanRank": 19, + "previousClanRank": 18, + "donations": 84, + "donationsReceived": 401 + }, + { + "tag": "#L8PY00L89", + "name": "Mr.YuAN", + "role": "member", + "expLevel": 87, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2346, + "versusTrophies": 1664, + "clanRank": 20, + "previousClanRank": 21, + "donations": 28, + "donationsReceived": 372 + }, + { + "tag": "#8Y9G2J0J2", + "name": "KD丶小北", + "role": "member", + "expLevel": 108, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2338, + "versusTrophies": 1755, + "clanRank": 21, + "previousClanRank": 20, + "donations": 158, + "donationsReceived": 241 + }, + { + "tag": "#P8VJC2222", + "name": "胜利者之书", + "role": "member", + "expLevel": 106, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2283, + "versusTrophies": 2294, + "clanRank": 22, + "previousClanRank": 22, + "donations": 266, + "donationsReceived": 575 + }, + { + "tag": "#9LVLGPJCU", + "name": "Mair灬冰锋", + "role": "admin", + "expLevel": 110, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2267, + "versusTrophies": 2989, + "clanRank": 23, + "previousClanRank": 23, + "donations": 569, + "donationsReceived": 198 + }, + { + "tag": "#PCPQ2VRPU", + "name": "买包辣条唯天下", + "role": "member", + "expLevel": 79, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2140, + "versusTrophies": 2033, + "clanRank": 24, + "previousClanRank": 24, + "donations": 37, + "donationsReceived": 57 + }, + { + "tag": "#YVVYUPRUU", + "name": "Hhh的小号", + "role": "member", + "expLevel": 93, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2139, + "versusTrophies": 2515, + "clanRank": 25, + "previousClanRank": 25, + "donations": 1, + "donationsReceived": 153 + }, + { + "tag": "#RU9PYU02", + "name": "素墨琴弦", + "role": "coLeader", + "expLevel": 137, + "league": { + "id": 29000000, + "name": "Unranked", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png" + } + }, + "trophies": 2094, + "versusTrophies": 1991, + "clanRank": 26, + "previousClanRank": 26, + "donations": 0, + "donationsReceived": 0 + }, + { + "tag": "#809QQCV8P", + "name": "加水", + "role": "member", + "expLevel": 133, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2082, + "versusTrophies": 1918, + "clanRank": 27, + "previousClanRank": 37, + "donations": 20, + "donationsReceived": 197 + }, + { + "tag": "#PLQP0LQ9Q", + "name": "咸鱼", + "role": "admin", + "expLevel": 110, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2075, + "versusTrophies": 2081, + "clanRank": 28, + "previousClanRank": 28, + "donations": 65, + "donationsReceived": 1048 + }, + { + "tag": "#2LY8PJCPP", + "name": "lu\u2006ta", + "role": "coLeader", + "expLevel": 133, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2061, + "versusTrophies": 2059, + "clanRank": 29, + "previousClanRank": 27, + "donations": 1663, + "donationsReceived": 1134 + }, + { + "tag": "#2RGPC0PYJ", + "name": "我是新手营", + "role": "admin", + "expLevel": 138, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2034, + "versusTrophies": 2315, + "clanRank": 30, + "previousClanRank": 29, + "donations": 99, + "donationsReceived": 0 + }, + { + "tag": "#Y8GG2JUU8", + "name": "Zzzzzzz", + "role": "admin", + "expLevel": 84, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2034, + "versusTrophies": 1862, + "clanRank": 31, + "previousClanRank": 30, + "donations": 0, + "donationsReceived": 0 + }, + { + "tag": "#L2UGQUVUG", + "name": "谁知道", + "role": "member", + "expLevel": 71, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 1959, + "versusTrophies": 1748, + "clanRank": 32, + "previousClanRank": 31, + "donations": 0, + "donationsReceived": 281 + }, + { + "tag": "#2LPV9JPPQ", + "name": "隐姓埋名,葬在幽冥", + "role": "leader", + "expLevel": 145, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 1941, + "versusTrophies": 2355, + "clanRank": 33, + "previousClanRank": 34, + "donations": 1305, + "donationsReceived": 310 + }, + { + "tag": "#8G2V99VL0", + "name": "holy high", + "role": "coLeader", + "expLevel": 66, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 1941, + "versusTrophies": 1246, + "clanRank": 34, + "previousClanRank": 32, + "donations": 85, + "donationsReceived": 892 + }, + { + "tag": "#PGLLRVVU8", + "name": "A.mbition", + "role": "member", + "expLevel": 99, + "league": { + "id": 29000009, + "name": "Gold League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png" + } + }, + "trophies": 1939, + "versusTrophies": 2286, + "clanRank": 35, + "previousClanRank": 33, + "donations": 156, + "donationsReceived": 243 + }, + { + "tag": "#LLYRUGYC9", + "name": "懒人弈", + "role": "member", + "expLevel": 74, + "league": { + "id": 29000009, + "name": "Gold League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png" + } + }, + "trophies": 1874, + "versusTrophies": 1779, + "clanRank": 36, + "previousClanRank": 35, + "donations": 388, + "donationsReceived": 182 + }, + { + "tag": "#PJUY2YU80", + "name": "屮神屮", + "role": "member", + "expLevel": 97, + "league": { + "id": 29000009, + "name": "Gold League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png" + } + }, + "trophies": 1869, + "versusTrophies": 2284, + "clanRank": 37, + "previousClanRank": 36, + "donations": 0, + "donationsReceived": 91 + }, + { + "tag": "#LY8QL0GG", + "name": "唐顿庄园", + "role": "member", + "expLevel": 123, + "league": { + "id": 29000000, + "name": "Unranked", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png" + } + }, + "trophies": 1808, + "versusTrophies": 1822, + "clanRank": 38, + "previousClanRank": 38, + "donations": 0, + "donationsReceived": 0 + }, + { + "tag": "#LLVR0CCUJ", + "name": "BeijudeyiB", + "role": "admin", + "expLevel": 57, + "league": { + "id": 29000009, + "name": "Gold League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png" + } + }, + "trophies": 1788, + "versusTrophies": 1067, + "clanRank": 39, + "previousClanRank": 39, + "donations": 0, + "donationsReceived": 260 + }, + { + "tag": "#UYRY8LUL", + "name": "Archer、", + "role": "admin", + "expLevel": 116, + "league": { + "id": 29000000, + "name": "Unranked", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png" + } + }, + "trophies": 1768, + "versusTrophies": 1480, + "clanRank": 40, + "previousClanRank": 40, + "donations": 0, + "donationsReceived": 0 + } + ] +} diff --git a/json_example/clan_detail.json.bak b/json_example/clan_detail.json.bak new file mode 100644 index 0000000..1cb6459 --- /dev/null +++ b/json_example/clan_detail.json.bak @@ -0,0 +1,1057 @@ +{ + "tag": "#PCCR9LQU", + "name": "\\u98ce\\u6708\\u9601", + "type": "inviteOnly", + "description": "\\u2460\\u548c\\u8c10 \\u6709\\u7231 \\u4e92\\u52a9 \\u8d85\\u8d8a\\ud83c\\udde8\\ud83c\\uddf3\\n\\u2461\\u53c2\\u6218\\u6210\\u5458\\u7075\\u6d3b\\u5207\\u6362\\u4f5c\\u6218\\u72b6\\u6001\\uff08\\u6362\\u724c\\u5b50\\uff09\\ud83c\\udf4e\\ud83c\\udf4f\\n\\u2462\\u52b3\\u8005\\u591a\\u5f97\\uff0c\\u4e0d\\u670d\\u6765\\u8fa9\\ud83d\\ude0e\\n\\u2463\\u901f\\u672c\\u3001\\u4f38\\u624b\\u515a\\u7ed5\\u8def\\ud83d\\udc4a\\ud83d\\udc4a\\u00a0\\u00a0\\u00a0\\u00a0 \\n\\u2464Q\\u7fa4335672475 Vx\\u627e\\u9996\\u9886 \\u4e0d\\u52a0\\u4e0d\\u7559\\u2708\\ufe0f\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0 \\n\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0 \\n\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0", + "location": { + "id": 32000056, + "name": "China", + "isCountry": true, + "countryCode": "CN" + }, + "badgeUrls": { + "small": "https://api-assets.clashofclans.com/badges/70/IQ1xLl2Jqa-eCIy-MLH9G8RcI1UFNTnoJ28YoQRNqlY.png", + "large": "https://api-assets.clashofclans.com/badges/512/IQ1xLl2Jqa-eCIy-MLH9G8RcI1UFNTnoJ28YoQRNqlY.png", + "medium": "https://api-assets.clashofclans.com/badges/200/IQ1xLl2Jqa-eCIy-MLH9G8RcI1UFNTnoJ28YoQRNqlY.png" + }, + "clanLevel": 12, + "clanPoints": 25717, + "clanVersusPoints": 24710, + "requiredTrophies": 1700, + "warFrequency": "always", + "warWinStreak": 2, + "warWins": 295, + "isWarLogPublic": false, + "members": 48, + "memberList": [ + { + "tag": "#8JG09J8PR", + "name": "\\u4f60\\u4e0d\\u61c2\\u6211\\u7684\\u57fa\\u5730", + "role": "member", + "expLevel": 145, + "league": { + "id": 29000017, + "name": "Champion League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/kLWSSyq7vJiRiCantiKCoFuSJOxief6R1ky6AyfB8q0.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/kLWSSyq7vJiRiCantiKCoFuSJOxief6R1ky6AyfB8q0.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/kLWSSyq7vJiRiCantiKCoFuSJOxief6R1ky6AyfB8q0.png" + } + }, + "trophies": 3549, + "versusTrophies": 2857, + "clanRank": 1, + "previousClanRank": 1, + "donations": 1639, + "donationsReceived": 905 + }, + { + "tag": "#8QVPRY0C0", + "name": "\\u8c01\\u77e5\\u9053", + "role": "admin", + "expLevel": 121, + "league": { + "id": 29000016, + "name": "Champion League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/JmmTbspV86xBigM7OP5_SjsEDPuE7oXjZC9aOy8xO3s.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/JmmTbspV86xBigM7OP5_SjsEDPuE7oXjZC9aOy8xO3s.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/JmmTbspV86xBigM7OP5_SjsEDPuE7oXjZC9aOy8xO3s.png" + } + }, + "trophies": 3167, + "versusTrophies": 2628, + "clanRank": 2, + "previousClanRank": 3, + "donations": 3371, + "donationsReceived": 838 + }, + { + "tag": "#89Y0PLUV8", + "name": "\\u4e8c\\u5b9d", + "role": "coLeader", + "expLevel": 200, + "league": { + "id": 29000016, + "name": "Champion League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/JmmTbspV86xBigM7OP5_SjsEDPuE7oXjZC9aOy8xO3s.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/JmmTbspV86xBigM7OP5_SjsEDPuE7oXjZC9aOy8xO3s.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/JmmTbspV86xBigM7OP5_SjsEDPuE7oXjZC9aOy8xO3s.png" + } + }, + "trophies": 3165, + "versusTrophies": 3870, + "clanRank": 3, + "previousClanRank": 5, + "donations": 1524, + "donationsReceived": 2420 + }, + { + "tag": "#YV2UL0RJ2", + "name": "\\u96ea\\u6708\\u98ce\\u82b1", + "role": "member", + "expLevel": 117, + "league": { + "id": 29000015, + "name": "Master League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png" + } + }, + "trophies": 3122, + "versusTrophies": 2328, + "clanRank": 4, + "previousClanRank": 4, + "donations": 111, + "donationsReceived": 304 + }, + { + "tag": "#LUCQPLJR", + "name": "\\u5988\\u5988\\u8bf4\\u5403\\u261e\\u814a\\u261c\\u6761\\u8d8a\\u591a\\u4eba\\u5c31\\u8d8a\\u5e05^", + "role": "coLeader", + "expLevel": 169, + "league": { + "id": 29000015, + "name": "Master League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/olUfFb1wscIH8hqECAdWbdB6jPm9R8zzEyHIzyBgRXc.png" + } + }, + "trophies": 2980, + "versusTrophies": 2440, + "clanRank": 5, + "previousClanRank": 2, + "donations": 5295, + "donationsReceived": 1252 + }, + { + "tag": "#22GU0VCQR", + "name": "annhuny", + "role": "coLeader", + "expLevel": 145, + "league": { + "id": 29000014, + "name": "Master League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png" + } + }, + "trophies": 2924, + "versusTrophies": 2538, + "clanRank": 6, + "previousClanRank": 7, + "donations": 1253, + "donationsReceived": 371 + }, + { + "tag": "#YJ8902C0", + "name": "\\u91c7\\u8611\\u83c7\\u7684\\u5c0f\\u59d1\\u5a18", + "role": "coLeader", + "expLevel": 118, + "league": { + "id": 29000014, + "name": "Master League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png" + } + }, + "trophies": 2896, + "versusTrophies": 1851, + "clanRank": 7, + "previousClanRank": 6, + "donations": 217, + "donationsReceived": 579 + }, + { + "tag": "#R09J2QQP", + "name": "\\u5c0f\\u660e", + "role": "coLeader", + "expLevel": 130, + "league": { + "id": 29000013, + "name": "Master League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png" + } + }, + "trophies": 2727, + "versusTrophies": 1868, + "clanRank": 8, + "previousClanRank": 9, + "donations": 211, + "donationsReceived": 503 + }, + { + "tag": "#9UPJQL20U", + "name": "\\u9f9a\\u5148\\u751f\\u069e\\u8d3c\\u5e05", + "role": "member", + "expLevel": 96, + "league": { + "id": 29000013, + "name": "Master League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png" + } + }, + "trophies": 2700, + "versusTrophies": 2135, + "clanRank": 9, + "previousClanRank": 8, + "donations": 617, + "donationsReceived": 568 + }, + { + "tag": "#YPURU9VYL", + "name": "blk", + "role": "coLeader", + "expLevel": 118, + "league": { + "id": 29000013, + "name": "Master League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png" + } + }, + "trophies": 2649, + "versusTrophies": 2052, + "clanRank": 10, + "previousClanRank": 10, + "donations": 132, + "donationsReceived": 205 + }, + { + "tag": "#LP2Y8C9LL", + "name": "\\u613f\\u5ff5\\u4f3c\\u98ce", + "role": "member", + "expLevel": 97, + "league": { + "id": 29000013, + "name": "Master League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/pSXfKvBKSgtvfOY3xKkgFaRQi0WcE28s3X35ywbIluY.png" + } + }, + "trophies": 2639, + "versusTrophies": 2357, + "clanRank": 11, + "previousClanRank": 11, + "donations": 1037, + "donationsReceived": 108 + }, + { + "tag": "#YU2RPYCJ", + "name": "\\u566c\\u9b42", + "role": "member", + "expLevel": 138, + "league": { + "id": 29000000, + "name": "Unranked", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png" + } + }, + "trophies": 2540, + "versusTrophies": 2757, + "clanRank": 12, + "previousClanRank": 12, + "donations": 0, + "donationsReceived": 0 + }, + { + "tag": "#P0LQV9UL9", + "name": "\\u864e\\u7259\\u641c\\u5f11\\u6225", + "role": "member", + "expLevel": 115, + "league": { + "id": 29000012, + "name": "Crystal League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png" + } + }, + "trophies": 2500, + "versusTrophies": 2713, + "clanRank": 13, + "previousClanRank": 13, + "donations": 178, + "donationsReceived": 196 + }, + { + "tag": "#8J0JPGPGP", + "name": "\\u8bdb\\u4ed9\\u5bb6\\u7684\\u5c0f\\u4ed9\\u5973", + "role": "member", + "expLevel": 112, + "league": { + "id": 29000012, + "name": "Crystal League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png" + } + }, + "trophies": 2444, + "versusTrophies": 2646, + "clanRank": 14, + "previousClanRank": 16, + "donations": 1, + "donationsReceived": 526 + }, + { + "tag": "#9VLGPCYYQ", + "name": "\\u597d\\u597d\\u5b51\\u5b53", + "role": "admin", + "expLevel": 136, + "league": { + "id": 29000012, + "name": "Crystal League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png" + } + }, + "trophies": 2443, + "versusTrophies": 2464, + "clanRank": 15, + "previousClanRank": 14, + "donations": 2190, + "donationsReceived": 583 + }, + { + "tag": "#2PQV92QUJ", + "name": "\\u828b\\u828b\\u828b\\u828b\\u5706", + "role": "coLeader", + "expLevel": 182, + "league": { + "id": 29000012, + "name": "Crystal League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/kSfTyNNVSvogX3dMvpFUTt72VW74w6vEsEFuuOV4osQ.png" + } + }, + "trophies": 2415, + "versusTrophies": 3273, + "clanRank": 16, + "previousClanRank": 15, + "donations": 2844, + "donationsReceived": 406 + }, + { + "tag": "#PGY8RJGQ0", + "name": "Queen\\u4e36\\u4e71\\u4e16\\u503e\\u57ce", + "role": "member", + "expLevel": 106, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2393, + "versusTrophies": 2358, + "clanRank": 17, + "previousClanRank": 19, + "donations": 279, + "donationsReceived": 0 + }, + { + "tag": "#998PLGCR", + "name": "\\u6d41\\u661f", + "role": "member", + "expLevel": 126, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2350, + "versusTrophies": 1278, + "clanRank": 18, + "previousClanRank": 21, + "donations": 84, + "donationsReceived": 401 + }, + { + "tag": "#L8PY00L89", + "name": "Mr.YuAN", + "role": "member", + "expLevel": 87, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2345, + "versusTrophies": 1664, + "clanRank": 19, + "previousClanRank": 17, + "donations": 27, + "donationsReceived": 311 + }, + { + "tag": "#8Y9G2J0J2", + "name": "KD\\u4e36\\u5c0f\\u5317", + "role": "member", + "expLevel": 107, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2338, + "versusTrophies": 1755, + "clanRank": 20, + "previousClanRank": 20, + "donations": 158, + "donationsReceived": 210 + }, + { + "tag": "#YUYJRQUJ2", + "name": "\\u4eba\\u751f\\u6709\\u68a6\\uff0c\\u5404\\u81ea\\u7cbe\\u5f69", + "role": "admin", + "expLevel": 117, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2323, + "versusTrophies": 2331, + "clanRank": 21, + "previousClanRank": 30, + "donations": 0, + "donationsReceived": 10890 + }, + { + "tag": "#P8VJC2222", + "name": "\\u80dc\\u5229\\u8005\\u4e4b\\u4e66", + "role": "member", + "expLevel": 106, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2295, + "versusTrophies": 2205, + "clanRank": 22, + "previousClanRank": 18, + "donations": 219, + "donationsReceived": 451 + }, + { + "tag": "#9LVLGPJCU", + "name": "Mair\\u706c\\u51b0\\u950b", + "role": "admin", + "expLevel": 109, + "league": { + "id": 29000011, + "name": "Crystal League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/jhP36EhAA9n1ADafdQtCP-ztEAQjoRpY7cT8sU7SW8A.png" + } + }, + "trophies": 2271, + "versusTrophies": 2991, + "clanRank": 23, + "previousClanRank": 22, + "donations": 564, + "donationsReceived": 132 + }, + { + "tag": "#YVVYUPRUU", + "name": "Hhh\\u7684\\u5c0f\\u53f7", + "role": "member", + "expLevel": 92, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2122, + "versusTrophies": 2515, + "clanRank": 24, + "previousClanRank": 25, + "donations": 1, + "donationsReceived": 92 + }, + { + "tag": "#RU9PYU02", + "name": "\\u7d20\\u58a8\\u7434\\u5f26", + "role": "coLeader", + "expLevel": 137, + "league": { + "id": 29000000, + "name": "Unranked", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png" + } + }, + "trophies": 2094, + "versusTrophies": 1991, + "clanRank": 25, + "previousClanRank": 26, + "donations": 0, + "donationsReceived": 0 + }, + { + "tag": "#2LY8PJCPP", + "name": "lu\\u2006ta", + "role": "coLeader", + "expLevel": 133, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2083, + "versusTrophies": 2059, + "clanRank": 26, + "previousClanRank": 29, + "donations": 1530, + "donationsReceived": 1039 + }, + { + "tag": "#PLQP0LQ9Q", + "name": "\\u54b8\\u9c7c", + "role": "admin", + "expLevel": 110, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2076, + "versusTrophies": 2081, + "clanRank": 27, + "previousClanRank": 31, + "donations": 65, + "donationsReceived": 860 + }, + { + "tag": "#Y8GG2JUU8", + "name": "Zzzzzzz", + "role": "admin", + "expLevel": 84, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2034, + "versusTrophies": 1862, + "clanRank": 28, + "previousClanRank": 27, + "donations": 0, + "donationsReceived": 0 + }, + { + "tag": "#2RGPC0PYJ", + "name": "\\u6211\\u662f\\u65b0\\u624b\\u8425", + "role": "admin", + "expLevel": 138, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2025, + "versusTrophies": 2315, + "clanRank": 29, + "previousClanRank": 32, + "donations": 99, + "donationsReceived": 0 + }, + { + "tag": "#L2UGQUVUG", + "name": "\u8c01\u77e5\u9053", + "role": "member", + "expLevel": 71, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2017, + "versusTrophies": 1720, + "clanRank": 30, + "previousClanRank": 34, + "donations": 0, + "donationsReceived": 232 + }, + { + "tag": "#8G2V99VL0", + "name": "holy high", + "role": "coLeader", + "expLevel": 66, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 2001, + "versusTrophies": 1217, + "clanRank": 31, + "previousClanRank": 23, + "donations": 70, + "donationsReceived": 749 + }, + { + "tag": "#2LPV9JPPQ", + "name": "\\u9690\\u59d3\\u57cb\\u540d\\uff0c\\u846c\\u5728\\u5e7d\\u51a5", + "role": "leader", + "expLevel": 145, + "league": { + "id": 29000010, + "name": "Crystal League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Hyqco7bHh0Q81xB8mSF_ZhjKnKcTmJ9QEq9QGlsxiKE.png" + } + }, + "trophies": 1970, + "versusTrophies": 2249, + "clanRank": 32, + "previousClanRank": 33, + "donations": 1225, + "donationsReceived": 283 + }, + { + "tag": "#PGLLRVVU8", + "name": "A.mbition", + "role": "member", + "expLevel": 99, + "league": { + "id": 29000009, + "name": "Gold League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png" + } + }, + "trophies": 1911, + "versusTrophies": 2286, + "clanRank": 33, + "previousClanRank": 36, + "donations": 76, + "donationsReceived": 182 + }, + { + "tag": "#LLYRUGYC9", + "name": "\\u61d2\\u4eba\\u5f08", + "role": "member", + "expLevel": 73, + "league": { + "id": 29000009, + "name": "Gold League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png" + } + }, + "trophies": 1883, + "versusTrophies": 1686, + "clanRank": 34, + "previousClanRank": 35, + "donations": 348, + "donationsReceived": 152 + }, + { + "tag": "#PJUY2YU80", + "name": "\\u5c6e\\u795e\\u5c6e", + "role": "member", + "expLevel": 97, + "league": { + "id": 29000009, + "name": "Gold League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png" + } + }, + "trophies": 1869, + "versusTrophies": 2284, + "clanRank": 35, + "previousClanRank": 0, + "donations": 0, + "donationsReceived": 71 + }, + { + "tag": "#LY8QL0GG", + "name": "\\u5510\\u987f\\u5e84\\u56ed", + "role": "member", + "expLevel": 123, + "league": { + "id": 29000000, + "name": "Unranked", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png" + } + }, + "trophies": 1808, + "versusTrophies": 1822, + "clanRank": 36, + "previousClanRank": 38, + "donations": 0, + "donationsReceived": 0 + }, + { + "tag": "#LQ0Q88Y9Y", + "name": "\\u58a8\\u96e8\\u6d45\\u6b87", + "role": "admin", + "expLevel": 79, + "league": { + "id": 29000009, + "name": "Gold League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png" + } + }, + "trophies": 1801, + "versusTrophies": 2004, + "clanRank": 37, + "previousClanRank": 37, + "donations": 250, + "donationsReceived": 252 + }, + { + "tag": "#LLVR0CCUJ", + "name": "BeijudeyiB", + "role": "admin", + "expLevel": 56, + "league": { + "id": 29000009, + "name": "Gold League I", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/CorhMY9ZmQvqXTZ4VYVuUgPNGSHsO0cEXEL5WYRmB2Y.png" + } + }, + "trophies": 1795, + "versusTrophies": 1067, + "clanRank": 38, + "previousClanRank": 39, + "donations": 0, + "donationsReceived": 210 + }, + { + "tag": "#UYRY8LUL", + "name": "Archer\\u3001", + "role": "admin", + "expLevel": 116, + "league": { + "id": 29000000, + "name": "Unranked", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png" + } + }, + "trophies": 1768, + "versusTrophies": 1480, + "clanRank": 39, + "previousClanRank": 40, + "donations": 0, + "donationsReceived": 0 + }, + { + "tag": "#829PLJUJJ", + "name": "minerva", + "role": "member", + "expLevel": 105, + "league": { + "id": 29000008, + "name": "Gold League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Y6CveuHmPM_oiOic2Yet0rYL9AFRYW0WA0u2e44-YbM.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Y6CveuHmPM_oiOic2Yet0rYL9AFRYW0WA0u2e44-YbM.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Y6CveuHmPM_oiOic2Yet0rYL9AFRYW0WA0u2e44-YbM.png" + } + }, + "trophies": 1689, + "versusTrophies": 2068, + "clanRank": 40, + "previousClanRank": 41, + "donations": 3368, + "donationsReceived": 214 + }, + { + "tag": "#YRG8J0G2L", + "name": "Forever \u6c38\u6052", + "role": "admin", + "expLevel": 116, + "league": { + "id": 29000008, + "name": "Gold League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Y6CveuHmPM_oiOic2Yet0rYL9AFRYW0WA0u2e44-YbM.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Y6CveuHmPM_oiOic2Yet0rYL9AFRYW0WA0u2e44-YbM.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Y6CveuHmPM_oiOic2Yet0rYL9AFRYW0WA0u2e44-YbM.png" + } + }, + "trophies": 1648, + "versusTrophies": 2429, + "clanRank": 41, + "previousClanRank": 42, + "donations": 340, + "donationsReceived": 243 + }, + { + "tag": "#LP82YVRQ0", + "name": "\\u6811\\u6218\\u8f93", + "role": "member", + "expLevel": 65, + "league": { + "id": 29000008, + "name": "Gold League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Y6CveuHmPM_oiOic2Yet0rYL9AFRYW0WA0u2e44-YbM.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Y6CveuHmPM_oiOic2Yet0rYL9AFRYW0WA0u2e44-YbM.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Y6CveuHmPM_oiOic2Yet0rYL9AFRYW0WA0u2e44-YbM.png" + } + }, + "trophies": 1623, + "versusTrophies": 1271, + "clanRank": 42, + "previousClanRank": 44, + "donations": 0, + "donationsReceived": 154 + }, + { + "tag": "#LLGL9CCYC", + "name": "\\u542c\\u8bf4\\uff0c\\u5f88\\u7b80\\u5355", + "role": "admin", + "expLevel": 62, + "league": { + "id": 29000008, + "name": "Gold League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/Y6CveuHmPM_oiOic2Yet0rYL9AFRYW0WA0u2e44-YbM.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/Y6CveuHmPM_oiOic2Yet0rYL9AFRYW0WA0u2e44-YbM.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/Y6CveuHmPM_oiOic2Yet0rYL9AFRYW0WA0u2e44-YbM.png" + } + }, + "trophies": 1622, + "versusTrophies": 1732, + "clanRank": 43, + "previousClanRank": 43, + "donations": 42, + "donationsReceived": 278 + }, + { + "tag": "#L299UGGRY", + "name": "\\u65e0\\u6cd5\\u65e0\\u5929", + "role": "member", + "expLevel": 50, + "league": { + "id": 29000007, + "name": "Gold League III", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/vd4Lhz5b2I1P0cLH25B6q63JN3Wt1j2NTMhOYpMPQ4M.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/vd4Lhz5b2I1P0cLH25B6q63JN3Wt1j2NTMhOYpMPQ4M.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/vd4Lhz5b2I1P0cLH25B6q63JN3Wt1j2NTMhOYpMPQ4M.png" + } + }, + "trophies": 1412, + "versusTrophies": 1736, + "clanRank": 44, + "previousClanRank": 45, + "donations": 0, + "donationsReceived": 180 + }, + { + "tag": "#LJQQLVRVQ", + "name": "\\u515c\\u515c\\u91cc\\u6709\\u7cd6", + "role": "member", + "expLevel": 27, + "league": { + "id": 29000005, + "name": "Silver League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/8OhXcwDJkenBH2kPH73eXftFOpHHRF-b32n0yrTqC44.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/8OhXcwDJkenBH2kPH73eXftFOpHHRF-b32n0yrTqC44.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/8OhXcwDJkenBH2kPH73eXftFOpHHRF-b32n0yrTqC44.png" + } + }, + "trophies": 1040, + "versusTrophies": 891, + "clanRank": 45, + "previousClanRank": 46, + "donations": 0, + "donationsReceived": 200 + }, + { + "tag": "#PPG02VL0J", + "name": "\\u4fd7\\u4eba", + "role": "member", + "expLevel": 39, + "league": { + "id": 29000005, + "name": "Silver League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/8OhXcwDJkenBH2kPH73eXftFOpHHRF-b32n0yrTqC44.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/8OhXcwDJkenBH2kPH73eXftFOpHHRF-b32n0yrTqC44.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/8OhXcwDJkenBH2kPH73eXftFOpHHRF-b32n0yrTqC44.png" + } + }, + "trophies": 1026, + "versusTrophies": 319, + "clanRank": 46, + "previousClanRank": 48, + "donations": 62, + "donationsReceived": 220 + }, + { + "tag": "#LQGY0CYGG", + "name": "\\u50b2\\u89c6\\u7fa4\\u96c4", + "role": "member", + "expLevel": 33, + "league": { + "id": 29000005, + "name": "Silver League II", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/8OhXcwDJkenBH2kPH73eXftFOpHHRF-b32n0yrTqC44.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/8OhXcwDJkenBH2kPH73eXftFOpHHRF-b32n0yrTqC44.png", + "medium": "https://api-assets.clashofclans.com/leagues/288/8OhXcwDJkenBH2kPH73eXftFOpHHRF-b32n0yrTqC44.png" + } + }, + "trophies": 936, + "versusTrophies": 1209, + "clanRank": 47, + "previousClanRank": 47, + "donations": 9, + "donationsReceived": 240 + }, + { + "tag": "#L2YP0U08Y", + "name": "\\u6e05\\u534e\\u517b\\u8001\\u9662", + "role": "member", + "expLevel": 8, + "league": { + "id": 29000000, + "name": "Unranked", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/leagues/72/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png", + "tiny": "https://api-assets.clashofclans.com/leagues/36/e--YMyIexEQQhE4imLoJcwhYn6Uy8KqlgyY3_kFV6t4.png" + } + }, + "trophies": 151, + "versusTrophies": 0, + "clanRank": 48, + "previousClanRank": 49, + "donations": 0, + "donationsReceived": 0 + } + ], + "labels": [ + { + "id": 56000000, + "name": "Clan Wars", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/labels/64/lXaIuoTlfoNOY5fKcQGeT57apz1KFWkN9-raxqIlMbE.png", + "medium": "https://api-assets.clashofclans.com/labels/128/lXaIuoTlfoNOY5fKcQGeT57apz1KFWkN9-raxqIlMbE.png" + } + }, + { + "id": 56000001, + "name": "Clan War League", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/labels/64/5w60_3bdtYUe9SM6rkxBRyV_8VvWw_jTlDS5ieU3IsI.png", + "medium": "https://api-assets.clashofclans.com/labels/128/5w60_3bdtYUe9SM6rkxBRyV_8VvWw_jTlDS5ieU3IsI.png" + } + }, + { + "id": 56000004, + "name": "Clan Games", + "iconUrls": { + "small": "https://api-assets.clashofclans.com/labels/64/7qU7tQGERiVITVG0CPFov1-BnFldu4bMN2gXML5bLIU.png", + "medium": "https://api-assets.clashofclans.com/labels/128/7qU7tQGERiVITVG0CPFov1-BnFldu4bMN2gXML5bLIU.png" + } + } + ] +} \ No newline at end of file diff --git a/middlewares.py b/middlewares.py new file mode 100644 index 0000000..c38ab04 --- /dev/null +++ b/middlewares.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# Create by Annhuny On 2019-12-29 22:34 +# File Name : middlewares.py +import json +import logging +import sys +import traceback +from django.http import JsonResponse +from django.utils.deprecation import MiddlewareMixin + +from DB.sqlalchemy_session import session +from errors import CustomError, DEFAULT_ERR_CODE + +logger = logging.getLogger('django.request') + + +class SessionClose(MiddlewareMixin): + def process_response(self, request, response): + session.close() + return response + + +class ExceptionHandler(MiddlewareMixin): + def process_exception(self, request, e): + if isinstance(e, CustomError): + res = {'code': e.code, 'msg': e.msg} + return JsonResponse(res) + else: + logger.warning(traceback.format_exc()) + return JsonResponse({ + 'code': DEFAULT_ERR_CODE, + 'msg': traceback.format_exc(), + }) diff --git a/middlewares/BasePreRequest.py b/middlewares/BasePreRequest.py deleted file mode 100644 index 6f54461..0000000 --- a/middlewares/BasePreRequest.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python -# Create by Annhuny On 2019-12-25 15:56 -# File Name : BasePreRequest.py -import os - -import yaml -from django.utils.deprecation import MiddlewareMixin - -import settings -from settings import PROJECT_ROOT_DIR, CFG_FILE_NAME - - -class BasePreRequestsMiddleware(MiddlewareMixin): - - def process_request(self, request): - cfg_file = os.path.join(PROJECT_ROOT_DIR, CFG_FILE_NAME) - settings.cfg = yaml.load(open(cfg_file)) diff --git a/middlewares/__init__.py b/middlewares/__init__.py deleted file mode 100644 index 085845f..0000000 --- a/middlewares/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env python -# Create by Annhuny On 2019-12-25 15:56 -# File Name : __init__.py.py \ No newline at end of file diff --git a/requirments b/requirments index 2e8a06c..de2df7d 100644 --- a/requirments +++ b/requirments @@ -4,6 +4,7 @@ certifi==2019.11.28 chardet==3.0.4 conf==0.4.1 Django==3.0.1 +djangorestframework==3.11.0 idna==2.8 mysql==0.0.2 mysql-client==0.0.1 @@ -13,9 +14,11 @@ protobuf==3.11.2 pyaml==19.12.0 pytz==2019.3 PyYAML==5.2 +redis==3.3.11 requests==2.22.0 six==1.13.0 SQLAlchemy==1.3.12 sqlparse==0.3.0 tzlocal==2.0.0 -urllib3==1.25.7 \ No newline at end of file +urllib3==1.25.7 +uWSGI==2.0.18 diff --git a/run_prod.sh b/run_prod.sh new file mode 100644 index 0000000..c2586ca --- /dev/null +++ b/run_prod.sh @@ -0,0 +1,10 @@ +# /usr/local/src/coc/venv/bin/python + +source ./venv/bin/activate + +uwsgi -d --ini uwsgi.ini + + + +# schedule +nohup python schedule/schedule_dashboard.py > /dev/null 2>&1 & \ No newline at end of file diff --git a/schedule/fetch_data.py b/schedule/fetch_data.py index 72ece54..8239bad 100644 --- a/schedule/fetch_data.py +++ b/schedule/fetch_data.py @@ -3,44 +3,42 @@ # File Name : fetch_data.py import datetime -import logging -from logging import config +import traceback from DB.sqlalchemy_session import session -from Models.models import FlowingData -from settings import LOGGING +from Models.models import DailyStatistic from spider.clan import ClanSpider -config.dictConfig(LOGGING) -logger = logging.getLogger('django.schedule') - def fetch_players_tag_list(): members = ClanSpider.clan_members() return [member.get('tag') for member in members] -def fetch_player_flowing_data(): - logger.info('--------------------------------------') - logger.info('- fetch players flowing data start -') - logger.info('--------------------------------------') +def fetch_player_daily_data(): + from schedule.schedule_dashboard import logger + + time_now = datetime.datetime.now().strftime('%Y-%m-%d %H:00:00') + logger.info('***** start fetching flowing data. datetimeTag: {} *****'.format(time_now)) - players_tag_list = fetch_players_tag_list() - for player_tag in players_tag_list: - player_data = ClanSpider.player_information(playerTag=player_tag) - player_data['datetimeTag'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') - logger.info(' fetch player tag: %s ' % player_tag) - session.add(FlowingData(**player_data)) + try: + players_tag_list = fetch_players_tag_list() + for player_tag in players_tag_list: + player_data = ClanSpider.player_information(player_tag=player_tag) + player_data['datetimeTag'] = time_now + logger.info('***** fetching playerTag: {} datetimeTag: {} *****'.format(player_tag, time_now)) + session.add(DailyStatistic(**player_data)) + session.commit() + session.close() + except Exception as e: + logger.error(traceback.format_exc()) - session.commit() - logger.info('--------------') - logger.info('- fetch ok -') - logger.info('--------------') + logger.info('***** fetching flowing data OK. datetimeTag: {} *****'.format(time_now)) return True if __name__ == '__main__': - fetch_player_flowing_data() + fetch_player_daily_data() diff --git a/schedule/schedule_dashboard.py b/schedule/schedule_dashboard.py new file mode 100644 index 0000000..a5b5faf --- /dev/null +++ b/schedule/schedule_dashboard.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# Create by Annhuny On 2019-12-27 00:09 +# File Name : schedule_dashboard.py +import logging +import traceback +from logging import config + +from apscheduler.schedulers.blocking import BlockingScheduler + +from schedule.fetch_data import fetch_player_daily_data +from settings import LOGGING + +config.dictConfig(LOGGING) +logger = logging.getLogger('django.schedule') + + +if __name__ == '__main__': + scheduler = BlockingScheduler() + scheduler.add_job(fetch_player_daily_data, 'interval', hours=2, misfire_grace_time=600, + start_date='2000-01-01 00:00:00', end_date='2030-01-01 00:00:00') + + try: + scheduler.start() + except (KeyboardInterrupt, SystemExit) as e: + logger.error(traceback.format_exc()) + diff --git a/schedule/scheduler_dashboard.py b/schedule/scheduler_dashboard.py deleted file mode 100644 index d795ba8..0000000 --- a/schedule/scheduler_dashboard.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python -# Create by Annhuny On 2019-12-27 00:09 -# File Name : scheduler_dashboard.py -import datetime - -from apscheduler.executors.pool import ThreadPoolExecutor -from apscheduler.schedulers.background import BackgroundScheduler -from apscheduler.schedulers.blocking import BlockingScheduler - -from schedule.fetch_data import fetch_player_flowing_data - - -def foo(): - print(datetime.datetime.now()) - - -if __name__ == '__main__': - scheduler = BlockingScheduler() - scheduler.add_job(fetch_player_flowing_data, 'interval', seconds=10, - start_date='2000-01-01 00:00:00', end_date='2030-01-01 00:00:00') - - try: - scheduler.start() - except (KeyboardInterrupt, SystemExit) as e: - print(e) - diff --git a/settings.py b/settings.py index 1e0a59b..a6510ee 100644 --- a/settings.py +++ b/settings.py @@ -13,11 +13,10 @@ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) +from config import conf + BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) PROJECT_ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) -CFG_FILE_NAME = 'config.yml' - -cfg = {} # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ @@ -26,10 +25,9 @@ SECRET_KEY = 'rmrs8mtd+$l9a705*m(6brk=@@a6)mn77xn3r1w@qso_4pja9j' # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = [] +DEBUG = True if conf.get('debug') else False +ALLOWED_HOSTS = ['*'] # Application definition @@ -50,7 +48,8 @@ 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', - # 'middlewares.BasePreRequest.BasePreRequestsMiddleware' + 'middlewares.SessionClose', + 'middlewares.ExceptionHandler', ] ROOT_URLCONF = 'urls' @@ -58,8 +57,7 @@ TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(BASE_DIR, 'coc/templates')] - , + 'DIRS': [os.path.join(BASE_DIR, 'coc/templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -72,6 +70,10 @@ }, ] +STATICFILES_DIRS = [ + os.path.join(BASE_DIR, 'static'), +] + WSGI_APPLICATION = 'wsgi.application' @@ -124,6 +126,9 @@ STATIC_URL = '/static/' +STATICFILES_DIRS = ( + os.path.join(BASE_DIR, 'static'), +) # log config BASE_LOG_DIR = os.path.join(PROJECT_ROOT_DIR, 'logs') @@ -135,7 +140,7 @@ 'disable_existing_loggers': False, 'formatters': { 'verbose': { - 'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}', + 'format': '{levelname} {asctime} {filename:s} @ {module} {process:d} {thread:d} \n {message}', 'style': '{', }, 'simple': { @@ -155,30 +160,29 @@ 'class': 'logging.StreamHandler', 'formatter': 'simple' }, - # 'mail_admins': { - # 'level': 'ERROR', - # 'class': 'django.utils.log.AdminEmailHandler', - # 'formatter': 'verbose', - # }, - 'file': { + 'django_request': { 'level': 'INFO', - 'class': 'logging.FileHandler', - 'filename': os.path.join(BASE_LOG_DIR, 'debug.log'), + 'filename': os.path.join(BASE_LOG_DIR, 'django_request.log'), + 'class': 'logging.handlers.RotatingFileHandler', + 'maxBytes': 1024 * 1024 * 25, + 'formatter': 'verbose', + }, + 'django_schedule': { + 'level': 'INFO', + 'filename': os.path.join(BASE_LOG_DIR, 'django_schedule.log'), + 'class': 'logging.handlers.RotatingFileHandler', + 'maxBytes': 1024 * 1024 * 25, 'formatter': 'verbose', }, }, 'loggers': { - 'django': { - 'handlers': ['console', 'file'], - 'propagate': True, - }, 'django.request': { - 'handlers': ['file'], - 'level': 'WARNING', - 'propagate': False, + 'handlers': ['django_request', 'console'] if DEBUG else ['django_request'], + 'level': 'INFO', + 'propagate': True, }, 'django.schedule': { - 'handlers': ['file'], + 'handlers': ['django_schedule', 'console'] if DEBUG else ['django_schedule'], 'level': 'INFO', 'propagate': False, }, diff --git a/spider/clan.py b/spider/clan.py index c84c37e..d98063c 100644 --- a/spider/clan.py +++ b/spider/clan.py @@ -12,45 +12,23 @@ class ClanSpider(BaseSpider): @classmethod def clan_detail(cls, **kwargs): - cls.api_url = '%s/%s/%s' % (cls.api_url, 'clans', quote(cls.clan_tag, 'utf-8')) - res = cls.req.get(cls.api_url) + api_url = '%s/%s/%s' % (cls.api_url, 'clans', quote('#' + cls.clan_tag, 'utf-8')) + res = cls.req.get(api_url) return res.json() @classmethod def clan_members(cls, **kwargs): - # cls.api_url = '%s/%s/%s/%s' % (cls.api_url, 'clans', quote(cls.clanTag, 'utf-8'), 'members') - # res = cls.req.get(cls.api_url) - # return res.json().get('items', {}) - return [{ - "tag": "#89Y0PLUV8", - "name": "二宝", - "role": "coLeader", - "expLevel": 198, - "league": { - "id": 29000017, - "name": "Champion League II", - "iconUrls": { - "small": "https://api-assets.clashofclans.com/leagues/72/kLWSSyq7vJiRiCantiKCoFuSJOxief6R1ky6AyfB8q0.png", - "tiny": "https://api-assets.clashofclans.com/leagues/36/kLWSSyq7vJiRiCantiKCoFuSJOxief6R1ky6AyfB8q0.png", - "medium": "https://api-assets.clashofclans.com/leagues/288/kLWSSyq7vJiRiCantiKCoFuSJOxief6R1ky6AyfB8q0.png" - } - }, - "trophies": 3657, - "versusTrophies": 3901, - "clanRank": 2, - "previousClanRank": 2, - "donations": 11450, - "donationsReceived": 10718 - }] + api_url = '%s/%s/%s/%s' % (cls.api_url, 'clans', quote('#' + cls.clan_tag, 'utf-8'), 'members') + res = cls.req.get(api_url) + return res.json().get('items', {}) @classmethod def player_information(cls, **kwargs): - # player_tag = kwargs.get('playerTag', '') - # cls.api_url = '%s/%s/%s' % (cls.api_url, 'players', quote(player_tag, 'utf-8')) - # res = cls.req.get(cls.api_url) - # res = res.json() - with open(PROJECT_ROOT_DIR + '/json_example/player_information.json', 'r') as f: - res = json.loads(f.read()) + player_tag = kwargs.get('player_tag', '') + api_url = '%s/%s/%s' % (cls.api_url, 'players', quote(player_tag, 'utf-8')) + res = cls.req.get(api_url).json() + # with open(PROJECT_ROOT_DIR + '/json_example/player_information.json', 'r') as f: + # res = json.loads(f.read()) active_index_arrays = ['Gold Grab', 'Elixir Escapade', 'Heroic Heist'] active_index_dict = {} @@ -60,7 +38,9 @@ def player_information(cls, **kwargs): return { 'tag': res.get('tag'), + 'name': res.get('name'), 'expLevel': res.get('expLevel'), + 'townHallLevel': res.get('townHallLevel'), 'trophies': res.get('trophies'), 'versusTrophies': res.get('versusTrophies'), 'attackWins': res.get('attackWins'), diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..457a60b --- /dev/null +++ b/templates/base.html @@ -0,0 +1,82 @@ + + +
+ + + + + {% block style %} + {% endblock %} +标签 | +昵称 | +等级 | +捐兵 | +收兵 | +进攻次数 | +捐收比 | +收捐比 | +
{{ item.tag }} | +{{ item.name }} | +{{ item.expLevel }} | +{{ item.donations }} | +{{ item.donationsReceived }} | +{{ item.attackWins }} | +{{ item.DR_ratio }} | +{{ item.RD_ratio }} | +