Commit 76dcd6dc authored by 李小芳's avatar 李小芳

更新代码

parents

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

# Default ignored files
/shelf/
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
</module>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6" project-jdk-type="Python SDK" />
<component name="PyCharmProfessionalAdvertiser">
<option name="shown" value="true" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/graces_es6.iml" filepath="$PROJECT_DIR$/.idea/graces_es6.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>
\ No newline at end of file
b221f63aaa0911e693b200163e00062b 308e33e020b111e6b76600163e001c72 dalianxuyingyiliaomeirong Dxuying
\ No newline at end of file
广东美恩整形美容医院 GZMEYL 2019-年度优秀颌面整形机构 2020-02-24 2020-08-28 0 0
南京艺星医疗美容 c4e818d43ce646599f15c4b42d1be614 2019-年度优秀鼻部整形机构 2020-02-24 2020-08-28 0 0
武汉美基元医疗美容医院 2ed317bc135211e68bbb00163e002fb3 2019-年度优秀口碑整形机构 2020-02-24 2020-08-28 0 0
长沙你美整形 d865c644028445748e292c77f6230599 2019-年度口碑整形机构 2020-02-24 2020-08-28 0 0
重庆万家燕整形外科医院 454fe69e00a64890b7b011854498807f 2019-年度优秀颌面整形机构 2020-02-24 2020-08-28 0 0
四川军大医学研究所附属医院 scjdyxyjfsyy 2019-年度实力整形机构 2020-02-24 2020-08-28 0 0
上海艺星 shyxylmryy2203 2019-年度优秀胸部整形机构 2020-02-24 2020-08-28 0 1
北京凤凰妇儿医院 c614856fe7c847c9b7f8a25f1aed40b8 2019-年度优秀私密整形机构 2020-02-24 2020-08-28 0 1
北京画美医疗美容(原长虹) fb38be6e52b34b6d8efe7a30d2c93022 2019-年度口碑整形机构 2020-02-24 2021-02-28 0 1
上海愉悦美联臣 shmlcylmryy 2019-年度优秀颌面整形机构 2020-02-24 2020-08-28 0 1
上海仁爱 shrayy 2019-年度优秀颌面整形机构 2020-02-24 2020-08-28 0 1
四川华美紫馨医学美容医院 schmzx 2019-年度口碑整形机构 2020-02-24 2020-08-28 0 1
北京凯润婷(原史三八)医疗美容医院 96ea37eef81d11e692f800163e000a4a 2019-年度人气整形机构 2020-02-24 2020-08-28 0 1
北京凯润婷(原史三八)口腔 a6e68171d66c4fb69275c82f76541c48 2019-年度人气整形机构 2020-02-24 2020-08-28 0 1
上海华美医疗美容医院 shhhuamei 2019-年度优秀眼部整形机构 2020-02-24 2020-08-28 0 1
张守玲 9ad334757bd8472891c9d9226981dfd1 2019-年度优秀私密整形医生 2020-02-24 2020-08-28 1 0
任召磊 02d70c57ffd042cb9eff23016514db2d 2019-年度优秀眼部整形医生 2020-02-24 2020-08-28 1 0
黄楷 7c9e39ec203a48fd8c8b48bdbaa38e24 2019-年度优秀鼻部整形医生 2020-02-24 2020-08-28 1 0
尤军 7413e93128be4da8a1111616d1649f0d 2019-年度优秀脂肪管理医生 2020-02-24 2020-08-28 1 0
赵善军 6786cb80650f11e6a42100163e001c72 2019-年度优秀脂肪管理医生 2020-02-24 2020-08-28 1 0
肖添有 6ca9d1f0c87d4d0288aa854f6c9b2cbe 2019-年度优秀颌面整形医生 2020-02-24 2020-08-28 1 1
FROM ccr.ccs.tencentyun.com/gm-base/gm-alpine-py2-ffmpeg:v1.0
MAINTAINER wph [wangpenghong@igengmei.com]
COPY ./requirements/common.txt /tmp
RUN apk add --no-cache --virtual .build-deps \
bzip2-dev \
coreutils \
dpkg-dev dpkg \
expat-dev \
findutils \
gcc \
gdbm-dev \
libc-dev \
libffi-dev \
libnsl-dev \
libressl-dev \
libtirpc-dev \
linux-headers \
make \
ncurses-dev \
pax-utils \
readline-dev \
sqlite-dev \
tcl-dev \
tk \
tk-dev \
xz-dev \
zlib-dev \
# 业务相关依赖和安装工具
linux-headers \
python2-dev \
librdkafka-dev \
mariadb-client \
mariadb-dev \
git \
openssh \
\
# 取消ssh第一次链接的确认
&& echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config \
&& apk add --no-cache mariadb-connector-c-dev libxml2-dev libxslt-dev librdkafka-dev \
&& apk add --no-cache jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev \
&& pip install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com --upgrade setuptools \
&& sed -i '/st_mysql_options options;/a unsigned int reconnect;' /usr/include/mysql/mysql.h \
&& pip install --no-cache-dir -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com -r /tmp/common.txt \
&& mkdir -p /tmp/video_convert \
&& mkdir -p /data/log/gaia/graces_es6
COPY . /srv/apps/graces-es6/
WORKDIR /srv/apps/graces-es6/
# requirements文件中指定安装master分支的依赖每次构建镜像都会重新安装
RUN cat requirements/common.txt | grep master > /tmp/gm-requirements.txt \
&& pip install --no-deps --upgrade -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com -r /tmp/gm-requirements.txt \
&& apk del .build-deps
CMD gunicorn gaia.wsgi:application -w 6 -k gevent -b 0.0.0.0:8000 --worker-tmp-dir /dev/shm
@Library('gm-pipeline-library') _
pipeline {
agent any
options {
// Console output add timestamps
timestamps()
// Disallow concurrent executions of the Pipeline
disableConcurrentBuilds()
// On failure, retry the entire Pipeline the specified number of times.
retry(1)
}
parameters {
choice(name: 'cache', choices: ['', '--no-cache'], description: 'docker build 是否使用cache,默认使用,不使用为--no-cache')
}
environment {
// Image Tag branch.time.hash
TAG = dockerTag()
// Image Full Tag
IMAGE = "${DOCKER_REGISTRY}/gm-backend/graces-es6:$TAG"
}
stages {
stage("Begin") {
steps {
dingNotify "before"
}
}
stage('Build Image') {
steps {
sh "docker build . ${params.cache} -f ./Dockerfile -t $IMAGE"
sh "docker push $IMAGE"
}
}
}
post {
always {
dingNotify "after", "${currentBuild.currentResult}"
}
}
}
GAIA
====
说明: 远程调用的参数和返回值会通过 json 序列化, 因此 dict 的 key 必须是字符串.
本地运行gaia服务器方法:
安装依赖
pip install -r requirements/dev.txt
增加rpc的相关配置
cp gaia/rpcd.json.demo gaia/rpcd.json
如果需要修改响应的RPC地址,gaia/rpcd.json中修改。
bingo
HELIOS_ROUTE_TABLE_FOR_DEBUG="$(<gaia/rpcd.json)" python manage.py runserver
# Commond
目录:api/management/commands
执行方式
`python manage.py command_name`
|命令|描述|时间|
|---|---|---|
|relation_190507_service_with_tag|导入产品提供的美购service和tag关联的数据,数据来自 /tag.xlsx|2019.05.07|
#用户达人标志开始回退
# !/usr/bin/env python
# encoding=utf-8
from __future__ import absolute_import
import os
# set the default Django settings module for the 'celery' program.
# os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'gaia.settings')
import raven
from raven.contrib.celery import register_signal, register_logger_signal
from celery import Celery
from django.conf import settings
import _celery_init
class Celery(Celery):
"""wrap for celery.Celery."""
def on_configure(self):
# check if sentry settings provided
# 设置 gm-logging 初始化模式
os.environ.setdefault('DJANGO_CELERY_MODE', 'TRUE')
if not settings.SENTRY_CELERY_ENDPOINT:
return
client = raven.Client(settings.SENTRY_CELERY_ENDPOINT)
# register a custom filter to filter out duplicate logs
register_logger_signal(client)
# hook into the Celery error handler
register_signal(client)
app = Celery('gaia_tasks')
# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
File added
# !/usr/bin/env python
# encoding=utf-8
import os
import uuid
import time
import logging
from celery.signals import worker_process_init
from gm_logging.py_logging import AppHandler
@worker_process_init.connect
def init_task_service_worker(**kwargs):
"""
ONLY call this function in worker!
因为 gm-logging 初始化后不能 fork 否则会导致写入 kafka 的 BUG,因此将初始化过程放在这里。
"""
from rpc.app import initialize_gm_logging
initialize_gm_logging()
print(
'init_task_service_worker: worker process initialized, pid={}, ppid={}, kwargs={}'.format(
os.getpid(),
os.getppid(),
repr(kwargs),
)
)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
\ No newline at end of file
# coding:utf-8
from django.core.management.base import BaseCommand
from agile.models.tag import TagAttrRelation
from utils.execel import ExcelReader
class Command(BaseCommand):
"""
标签属性 关联 python manage.py attr_tag_related_map
"""
def handle(self, *args, **options):
print('START')
# 增加新映射关系
related_objects = []
excel = ExcelReader('/tmp/标签导入模板.xlsx')
for row in range(excel.row_number):
data = excel.read_row(row)
if len(data) < 2:
continue
parent_id = data[0]
child_id = data[1]
related_objects.append(TagAttrRelation(parent_id=parent_id, child_id=child_id))
TagAttrRelation.objects.bulk_create(related_objects)
print("Done")
# coding:utf-8
from datetime import datetime
from django.core.management.base import BaseCommand
from agile.models.tag import (
TagMapTag, TagV3, AttrTag, AttrTagSynonym, TagSynonym, TagV3Relation, TagAttrRelation, TagV3MapAttrTag
)
from gm_types.gaia import TAG_V3_TYPE, TAG_TYPE_ATTR
class Command(BaseCommand):
"""
属性转标签
"""
@staticmethod
def _get_tag_type_from_attr_type(attr_type):
if attr_type == TAG_TYPE_ATTR.FIRST_SYMPTOM:
return TAG_V3_TYPE.FIRST_SYMPTOM
elif attr_type == TAG_TYPE_ATTR.SYMPTOM:
return TAG_V3_TYPE.SECOND_SYMPTOM
elif attr_type in (TAG_TYPE_ATTR.MODE, TAG_TYPE_ATTR.FIRST_BRAND):
return TAG_V3_TYPE.FIRST_BRAND
elif attr_type == TAG_TYPE_ATTR.BRAND:
return TAG_V3_TYPE.SECOND_BRAND
elif attr_type == TAG_TYPE_ATTR.MACROSCOPIC_MODE:
return TAG_V3_TYPE.MACROSCOPIC_MODE
elif attr_type == TAG_TYPE_ATTR.FIRST_APPEAL:
return TAG_V3_TYPE.FIRST_APPEAL
elif attr_type == TAG_TYPE_ATTR.SECOND_APPEAL:
return TAG_V3_TYPE.SECOND_APPEAL
elif attr_type == TAG_TYPE_ATTR.FIRST_POSITION:
return TAG_V3_TYPE.FIRST_POSITION
elif attr_type == TAG_TYPE_ATTR.POSITION:
return TAG_V3_TYPE.SECOND_POSITION
elif attr_type == TAG_TYPE_ATTR.DRUG:
return TAG_V3_TYPE.DRUG
elif attr_type == TAG_TYPE_ATTR.INSTRUMENT:
return TAG_V3_TYPE.INSTRUMENT
elif attr_type == TAG_TYPE_ATTR.CONSUMABLES:
return TAG_V3_TYPE.CONSUMABLES
else:
return None
def _get_tag_from_attr(self, attr):
tag_type = self._get_tag_type_from_attr_type(attr.aggregate_type)
return TagV3.objects.filter(name=attr.name, tag_type=tag_type).first()
@staticmethod
def _gets_attr(start, size=100):
total = AttrTag.objects.filter().count()
if start > total:
return []
return AttrTag.objects.filter()[start: start + size]
def _create_tag_from_attrs(self, attrs):
if not attrs:
return
insert_tag_dict = {}
insert_tag_list = []
for attr in attrs:
tag_type = self._get_tag_type_from_attr_type(attr.aggregate_type)
exist_tag = TagV3.objects.filter(name=attr.name, tag_type=tag_type).first()
if exist_tag:
continue
if not attr.name:
continue
if insert_tag_dict.get(attr.name + str(tag_type)) is not None:
continue
insert_tag_list.append(TagV3(
name=attr.name,
homoionym=attr.homoionym,
tag_type=tag_type,
is_using_ai=attr.is_using_ai,
is_display=False,
is_online=attr.is_online,
))
insert_tag_dict[attr.name + str(tag_type)] = 1
if insert_tag_list:
TagV3.objects.bulk_create(insert_tag_list)
def _create_synonym_from_attrs(self, attrs):
if not attrs:
return
attr_ids = [item.id for item in attrs]
attr_synonym = AttrTagSynonym.objects.filter(tag_attr_id__in=attr_ids)
if not attr_synonym:
return
attr_synonym_dict = {item.tag_attr_id: item.name for item in attr_synonym}
insert_synonym_list = []
for attr in attrs:
tag_type = self._get_tag_type_from_attr_type(attr.aggregate_type)
tag = TagV3.objects.filter(name=attr.name, tag_type=tag_type).first()
if not tag:
continue
synonym = attr_synonym_dict.get(attr.id)
if not synonym:
continue
insert_synonym_list.append(TagSynonym(
name=synonym,
tag_id=tag.id,
tag_type=tag_type,
))
if insert_synonym_list:
TagSynonym.objects.bulk_create(insert_synonym_list)
def _create_all_relation_from_attrs(self, attrs):
# 标签全部创建完成后 才可以进行
if not attrs:
return
attr_ids = [item.id for item in attrs]
attr_dict = {item.id: item for item in attrs}
relations = TagAttrRelation.objects.filter(parent_id__in=attr_ids)
if not relations:
return
child_ids = [item.child_id for item in relations]
child_attrs = AttrTag.objects.filter(id__in=child_ids)
child_dict = {item.id: item for item in child_attrs}
insert_relation_dict = {}
insert_relation_list = []
for relation in relations:
parent_attr = attr_dict.get(relation.parent_id)
child_attr = child_dict.get(relation.child_id)
if not parent_attr or not child_attr:
continue
parent_tag = self._get_tag_from_attr(parent_attr)
if not parent_tag:
continue
child_tag = self._get_tag_from_attr(child_attr)
if not child_tag:
continue
exist_relation = TagV3Relation.objects.filter(parent_id=parent_tag.id, child_id=child_tag.id)
if exist_relation:
continue
if insert_relation_dict.get(parent_tag.id):
continue
insert_relation_list.append(TagV3Relation(
parent_id=parent_tag.id,
child_id=child_tag.id,
))
insert_relation_dict[parent_tag.id] = child_tag.id
if insert_relation_list:
TagV3Relation.objects.bulk_create(insert_relation_list)
@staticmethod
def _get_time_string(time):
return time.strftime('%Y-%m-%d %H:%M:%S %f')
def _update_tag_map(self, attr_tag_maps):
attr_ids = [item.tag_attr_id for item in attr_tag_maps]
attr_tag_map_dict = {item.tag_attr_id: item for item in attr_tag_maps}
attrs = AttrTag.objects.filter(id__in=attr_ids)
if not attrs:
return
for attr in attrs:
tag = self._get_tag_from_attr(attr)
attr_tag_map = attr_tag_map_dict.get(attr.id)
if not tag or not attr_tag_map:
continue
# 此处更新 会影响该model使用,需要调整此model数据使用地方的数据获取,tag_attr_id不再获取AttrTag,获取TagV3
TagV3MapAttrTag.objects.filter(tag_attr_id=attr_tag_map.tag_attr_id).update(tag_attr_id=tag.id)
def update_all_tag_map(self, size=100):
print 'start update_all_tag_map at {}'.format(self._get_time_string(datetime.now()))
qs = TagV3MapAttrTag.objects.filter()
start = 0
end = size
attr_tag_maps = qs[start: end]
while attr_tag_maps:
print 'update_all_tag_map dealing start is {} end is {} at {}'.format(
start, end, self._get_time_string(datetime.now()))
self._update_tag_map(attr_tag_maps)
start = end
end = end + size
attr_tag_maps = qs[start: end]
print 'end update_all_tag_map at {}'.format(self._get_time_string(datetime.now()))
def attr_to_tag_create(self):
print 'start attr_to_tag_create at {}'.format(self._get_time_string(datetime.now()))
start = 0
size = 100
attrs = self._gets_attr(start, size)
while attrs:
print 'attr_to_tag_create dealing start is {} at {}'.format(
start, self._get_time_string(datetime.now()))
self._create_tag_from_attrs(attrs)
self._create_synonym_from_attrs(attrs)
start = start + size
attrs = self._gets_attr(start, size)
print 'end attr_to_tag_create at {}'.format(self._get_time_string(datetime.now()))
def attr_relation_create(self):
print 'start attr_relation_create at {}'.format(self._get_time_string(datetime.now()))
start = 0
size = 100
attrs = self._gets_attr(start, size)
while attrs:
print 'attr_relation_create dealing start is {} at {}'.format(
start, self._get_time_string(datetime.now()))
self._create_all_relation_from_attrs(attrs)
start = start + size
attrs = self._gets_attr(start, size)
print 'end attr_relation_create at {}'.format(self._get_time_string(datetime.now()))
def handle(self, *args, **options):
print 'start deal at {}'.format(self._get_time_string(datetime.now()))
# 属性迁移为标签
self.attr_to_tag_create()
# 属性关联关系迁移
self.attr_relation_create()
# 标签与属性关联关系更新
self.update_all_tag_map()
print 'end deal at {}'.format(self._get_time_string(datetime.now()))
# coding:utf-8
from django.core.management.base import BaseCommand
from utils.execel import ExcelWriter
from gm_types.gaia import TAG_TYPE_ATTR, TAG_V3_TYPE
from agile.models.tag import (
TagV3,
AttrTag,
TagV3MapAttrTag,
TagMapOldTag,
TagAttrRelation,
)
from api.models import Tag
class TagService(object):
####### 老标签与属性标签关联 #########
@staticmethod
def list_names(attr_ids, _type):
return ", ".join(
list(
AttrTag.objects.filter(id__in=attr_ids, aggregate_type=_type).values_list("name", flat=True)
)
)
@classmethod
def get_names_by_attr_type(cls, obj, attr_type):
"""根据属性标签获取对应类型的属性名称列表。"""
attr_ids = cls.list_tag_attr_ids(obj)
return cls.list_names(attr_ids, attr_type)
@staticmethod
def list_tag_attr_ids(obj):
return list(TagV3MapAttrTag.objects.filter(tag_id=obj.id).values_list('tag_attr_id', flat=True))
@classmethod
def related_old_tags(cls, obj): # 关联老标签
old_tag_ids = TagMapOldTag.objects.filter(tag_id=obj.id).values_list('old_tag_id', flat=True)
return ", ".join(list(Tag.objects.filter(pk__in=old_tag_ids).values_list('name', flat=True)))
####### 属性标签关联 #########
@staticmethod
def list_child_ids(obj):
return list(TagAttrRelation.objects.filter(parent_id=obj.id).values_list('child_id', flat=True))
@classmethod
def list_type_children_names_by_parent(cls, obj, _type):
attr_ids = cls.list_child_ids(obj)
return cls.list_names(attr_ids, _type)
### 新标签
@classmethod
def xx_to_brand(cls, obj):
"""品牌"""
tag_ids = list(TagV3MapAttrTag.objects.filter(tag_attr_id=obj.id).values_list('tag_id', flat=True))
return ", ".join(
list(
TagV3.objects.filter(id__in=tag_ids, tag_type=TAG_V3_TYPE.BRAND).values_list("name", flat=True)
)
)
class Command(BaseCommand):
def handle(self, *args, **options):
excel = ExcelWriter("./tag_3.xlsx")
excel.create_sheet(u"项目")
excel.write_header([
u"项目标签",
u"一级部位", u"二级部位", u"一级药品仪器耗材", u"二级药品仪器耗材",
u"二级诉求", u"一级诉求", u"二级方式", u"一级方式",
u"老标签"
])
write_rows = []
for tag in TagV3.objects.filter(tag_type=TAG_V3_TYPE.NORMAL, is_online=True):
a = TagService.get_names_by_attr_type(tag, TAG_TYPE_ATTR.FIRST_POSITION) # 一级部位
b = TagService.get_names_by_attr_type(tag, TAG_TYPE_ATTR.POSITION) # 二级部位
c = TagService.get_names_by_attr_type(tag, TAG_TYPE_ATTR.MODE) # 一级药品仪器耗材
d = TagService.get_names_by_attr_type(tag, TAG_TYPE_ATTR.BRAND) # 二级药品仪器耗材
e = TagService.get_names_by_attr_type(tag, TAG_TYPE_ATTR.SECOND_APPEAL) # 二级诉求
f = TagService.get_names_by_attr_type(tag, TAG_TYPE_ATTR.FIRST_APPEAL) # 一级诉求
g = TagService.get_names_by_attr_type(tag, TAG_TYPE_ATTR.MODE) # 二级方式
h = TagService.get_names_by_attr_type(tag, TAG_TYPE_ATTR.MACROSCOPIC_MODE) # 一级方式
i = TagService.related_old_tags(tag) # 老标签
write_rows.append([tag.name, a, b, c, d, e, f, g, h, i])
excel.write_rows(2, write_rows)
excel.save()
excel.create_sheet(u"一级诉求")
excel.write_header([
u"一级诉求", u"二级诉求"
])
write_rows = []
for attr in AttrTag.objects.filter(aggregate_type=TAG_TYPE_ATTR.FIRST_APPEAL): # 一级诉求
# SECOND_APPEAL 二级诉求
names = TagService.list_type_children_names_by_parent(attr, TAG_TYPE_ATTR.SECOND_APPEAL)
write_rows.append([attr.name, names])
excel.write_rows(2, write_rows)
excel.save()
excel.create_sheet(u"一级部位")
excel.write_header([
u"一级部位", u"二级部位"
])
write_rows = []
for attr in AttrTag.objects.filter(aggregate_type=TAG_TYPE_ATTR.FIRST_POSITION): # 一级部位
# POSITION 二级部位
names = TagService.list_type_children_names_by_parent(attr, TAG_TYPE_ATTR.POSITION)
write_rows.append([attr.name, names])
excel.write_rows(2, write_rows)
excel.save()
excel.create_sheet(u"一级方式")
excel.write_header([
u"一级方式", u"1级药品仪器耗材"
])
write_rows = []
for attr in AttrTag.objects.filter(aggregate_type=TAG_TYPE_ATTR.MACROSCOPIC_MODE): # 一级方式
# FIRST_BRAND 1级药品仪器耗材
names = TagService.list_type_children_names_by_parent(attr, TAG_TYPE_ATTR.MODE)
write_rows.append([attr.name, names])
excel.write_rows(2, write_rows)
excel.save()
excel.create_sheet(u"1级药品仪器耗材")
excel.write_header([
u"1级药品仪器耗材", u"2级药品仪器耗材"
])
write_rows = []
for attr in AttrTag.objects.filter(aggregate_type=TAG_TYPE_ATTR.MODE): # 1级药品仪器耗材
# BRAND 2级药品仪器耗材
names = TagService.list_type_children_names_by_parent(attr, TAG_TYPE_ATTR.BRAND)
write_rows.append([attr.name, names])
excel.write_rows(2, write_rows)
excel.save()
excel.create_sheet(u"2级药品仪器耗材")
excel.write_header([
u"2级药品仪器耗材", u"品牌"
])
write_rows = []
for attr in AttrTag.objects.filter(aggregate_type=TAG_TYPE_ATTR.BRAND): # 2级药品仪器耗材
# TAG_V3_TYPE.BRAND 品牌标签
names = TagService.xx_to_brand(attr)
write_rows.append([attr.name, names])
excel.write_rows(2, write_rows)
excel.save()
print('DONE')
This source diff could not be displayed because it is too large. You can view the blob instead.
# coding:utf-8
from django.core.management.base import BaseCommand
from utils.execel import ExcelReader
from agile.models.tag import TagMapOldTag
class Command(BaseCommand):
"""
下线 表api_tag_map_oldtag 中所有的映射关系
"""
def handle(self, *args, **options):
print('START')
# 下线之前的映射关系
TagMapOldTag.objects.all().update(is_online=False)
# 增加新映射关系
excel = ExcelReader('/tmp/录入标签关系.xlsx')
tag_map_list = []
for row in range(excel.row_number):
data = excel.read_row(row)
if len(data) < 4:
continue
tag_id = str( data[1])
old_tag_id = str(data[3])
if not (tag_id.isdigit() and old_tag_id.isdigit()):
continue
tag_map_list.append(TagMapOldTag(
tag_id=tag_id,
old_tag_id=old_tag_id,
))
i = 0
deal_count = 100
while i < len(tag_map_list):
TagMapOldTag.objects.bulk_create(tag_map_list[i: i + deal_count])
i += deal_count
print('DONE')
This source diff could not be displayed because it is too large. You can view the blob instead.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
from django.core.management.base import BaseCommand
from gm_types.gaia import (
AGILE_TAG_HERA_RECOMMEND_TAB_TYPE,
AGILE_TAG_RECOMMEND_TYPE,
)
from agile.models import AgileTagHeraRecommend
tab_type_mapping_tags = {
(AGILE_TAG_RECOMMEND_TYPE.TRACTATE, AGILE_TAG_HERA_RECOMMEND_TAB_TYPE.ALL): # 全部
[9535, 9510, 9669, 9670, 9509, 9532, 9518, 9508, 9505, 9511, 8, 21, 117, 31, 61],
(AGILE_TAG_RECOMMEND_TYPE.TRACTATE, AGILE_TAG_HERA_RECOMMEND_TAB_TYPE.PROJECT): # 项目
[117, 31, 1, 50, 35, 8, 21, 4, 28, 64, 60, 7, 61, 37, 4],
(AGILE_TAG_RECOMMEND_TYPE.TRACTATE, AGILE_TAG_HERA_RECOMMEND_TAB_TYPE.POSITION): # 部位
[169, 156, 120, 124, 332, 331, 330, 329, 306, 310, 303, 278, 360, 265, 271],
(AGILE_TAG_RECOMMEND_TYPE.TRACTATE, AGILE_TAG_HERA_RECOMMEND_TAB_TYPE.BRAND): # 品牌
[342, 344, 184, 168, 315, 294, 181, 190, 214, 309, 289],
(AGILE_TAG_RECOMMEND_TYPE.TRACTATE, AGILE_TAG_HERA_RECOMMEND_TAB_TYPE.INSTRUMENT): # 仪器
[223, 218, 122, 318, 324, 280, 251, 166],
}
class Command(BaseCommand):
def handle(self, *args, **kwargs):
print("BEGIN")
bulk_create_list = []
for k, v in tab_type_mapping_tags.items():
_recommend_type, _tab_type = k
base_kw = {
"agile_recommend_type": _recommend_type,
"agile_tab_type": _tab_type,
"is_online": True,
}
if AgileTagHeraRecommend.objects.filter(**base_kw).exists():
print("recommend_type {}、tab_type {} exists!".format(
AGILE_TAG_RECOMMEND_TYPE.getDesc(_recommend_type),
AGILE_TAG_HERA_RECOMMEND_TAB_TYPE.getDesc(_tab_type)
))
continue
else:
base_kw.update({
"agile_tag_sort_ids": json.dumps(v),
})
bulk_create_list.append(AgileTagHeraRecommend(**base_kw))
print("recommend_type {}、tab_type {} will create!".format(
AGILE_TAG_RECOMMEND_TYPE.getDesc(_recommend_type),
AGILE_TAG_HERA_RECOMMEND_TAB_TYPE.getDesc(_tab_type)
))
if bulk_create_list:
print("bulk create, lens {}".format(len(bulk_create_list)))
AgileTagHeraRecommend.objects.bulk_create(bulk_create_list)
print("END")
# coding:utf-8
import os
from django.core.management.base import BaseCommand
from django.db import IntegrityError
from gm_types.gaia import AGILE_TAG_CREATE_TYPE, AGILE_TAG_STYLE, AGILE_TAG_TYPE
from utils.execel import ExcelReader, ExcelWriter
from agile.models.agile_tag import AgileTag, AgileTagMapping, AgileTagType
AGILE_TAG_TYPE_MAP = {
u'项目': AGILE_TAG_TYPE.PROJECT,
u'-': AGILE_TAG_TYPE.UNDEFINED,
u'医院': AGILE_TAG_TYPE.HOSPITAL,
u'医生': AGILE_TAG_TYPE.DOCTOR,
u'仪器': AGILE_TAG_TYPE.INSTRUMENT,
u'品牌': AGILE_TAG_TYPE.BRAND,
u'部位': AGILE_TAG_TYPE.POSITION,
u'症状': AGILE_TAG_TYPE.SYMPTOM,
u'材料': AGILE_TAG_TYPE.MATERIAL,
u'城市': AGILE_TAG_TYPE.CITY,
u'省份': AGILE_TAG_TYPE.PROVINCE,
u'国家': AGILE_TAG_TYPE.COUNTRY,
}
CREATE_TAG_TYPE_MAP = {
u'项目': AGILE_TAG_CREATE_TYPE.SYSTEM,
u'-': AGILE_TAG_CREATE_TYPE.OPERATOR,
u'医生': AGILE_TAG_CREATE_TYPE.SYSTEM,
u'医院': AGILE_TAG_CREATE_TYPE.SYSTEM,
}
EXCEL_SHEET = [u'医院', u'医生']
def get_path():
parent_path = os.path.dirname(os.path.dirname(__file__))
path = parent_path + '/files/医院医生新标签映射表格.xlsx'
return path
class Command(BaseCommand):
"""
医生、医院标签
sync_agile_tag_v2
"""
def handle(self, *args, **options):
print('START')
excel_write = ExcelWriter("agile_tags.xlsx")
excel_read = ExcelReader(get_path())
for sheet in EXCEL_SHEET:
excel_read.sheet_select_by_name(sheet)
excel_write.create_sheet(sheet)
excel_write.write_header(['标签名称', '标签id'])
agile_tag_type = []
write_rows = []
for row in range(1, excel_read.row_number):
data = excel_read.read_row(row)
# data[0], data[1], data[2] 标签类型 老标签id 新标签name
if not any([data[0], data[1], data[2]]):
break
try:
agile = AgileTag.objects.create(
name=data[2],
create_tag_type=CREATE_TAG_TYPE_MAP[data[0]],
style=AGILE_TAG_STYLE.UNDEFINED
)
except:
continue
agile_tag_type.append(
AgileTagType(
agile_tag_id=agile.id,
agile_tag_type=AGILE_TAG_TYPE_MAP[data[0]]
)
)
write_rows.append([data[2], agile.id])
offset = 1000
while agile_tag_type:
AgileTagType.objects.bulk_create(agile_tag_type[:offset])
agile_tag_type = agile_tag_type[offset:]
excel_write.write_rows(2, write_rows)
excel_write.save()
print('DONE')
# coding:utf-8
from django.core.management.base import BaseCommand
from trans2es.utils.tasks import compute_doctor_score
class Command(BaseCommand):
""" 处理重复标签 """
def handle(self, *args, **options):
compute_doctor_score()
# coding:utf-8
import os
from django.core.management.base import BaseCommand
from django.db import IntegrityError
from gm_types.gaia import AGILE_TAG_CREATE_TYPE, AGILE_TAG_STYLE, AGILE_TAG_TYPE
from utils.execel import ExcelReader
from agile.models.agile_tag import AgileTag, AgileTagMapping, AgileTagType
AGILE_TAG_TYPE_MAP = {
u'项目': AGILE_TAG_TYPE.PROJECT,
u'-': AGILE_TAG_TYPE.UNDEFINED
}
CREATE_TAG_TYPE_MAP = {
u'项目': AGILE_TAG_CREATE_TYPE.SYSTEM,
u'-': AGILE_TAG_CREATE_TYPE.OPERATOR
}
def get_path():
parent_path = os.path.dirname(os.path.dirname(__file__))
path = parent_path + '/files/新老标签映射1.4.xlsx' # 文件上传地址确定
return path
class Command(BaseCommand):
"""
新老标签关系映射
sync_tag_agile_tag
"""
def handle(self, *args, **options):
print('START')
excel = ExcelReader(get_path())
excel.sheet_select_by_name(u"映射关系for后端")
for row in range(1, excel.row_number):
data = excel.read_row(row)
# data[0], data[1], data[2] 标签类型 老标签id 新标签name
if not any([data[0], data[1], data[2]]):
break
try:
agile = AgileTag.objects.create(
name=data[2],
create_tag_type=CREATE_TAG_TYPE_MAP[data[0]],
style=AGILE_TAG_STYLE.UNDEFINED
)
except IntegrityError:
agile = AgileTag.objects.get(name=data[2])
if not agile.is_online:
agile.is_online = True
agile.save(update_fields=['is_online'])
AgileTagType.objects.create(
agile_tag_id=agile.id,
agile_tag_type=AGILE_TAG_TYPE_MAP[data[0]]
)
raw_mapping_data = data[1]
if raw_mapping_data:
old_tag_mapping = str(data[1]).split(',')
else:
old_tag_mapping = []
agiletagmapping_list = []
for _id in old_tag_mapping:
tag_mapping = AgileTagMapping(
agile_tag_id=agile.id,
old_tag_id=int(_id)
)
agiletagmapping_list.append(tag_mapping)
AgileTagMapping.objects.bulk_create(agiletagmapping_list)
print('DONE')
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from django.core.management import BaseCommand
from gm_types.gaia import TAG_TYPE_ATTR
from agile.models import TagV3, AttrTag
_types = [
TAG_TYPE_ATTR.FIRST_APPEAL, TAG_TYPE_ATTR.SECOND_APPEAL,
TAG_TYPE_ATTR.MACROSCOPIC_MODE, TAG_TYPE_ATTR.MODE,
TAG_TYPE_ATTR.FIRST_POSITION, TAG_TYPE_ATTR.POSITION,
]
class Command(BaseCommand):
"""
python manage.py tag3_online
"""
def handle(self, *args, **options):
TagV3.objects.all().update(is_display=True, is_online=True)
AttrTag.objects.filter(aggregate_type__in=_types).update(is_online=True)
print('Done')
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from django.conf import settings
from django.core.management import BaseCommand
from gm_types.gaia import TAG_V3_TYPE
from agile.models.tag import TagMapCity, TagV3
from api.models import City
class Command(BaseCommand):
"""
python manage.py tag_city_map
"""
def handle(self, *args, **options):
city_tags = TagV3.objects.using(settings.SLAVE_DB_NAME).filter(
tag_type=TAG_V3_TYPE.CITY, is_online=True,
).values_list('id', 'name')
tags_name = {item[1]: item[0] for item in city_tags}
cities = City.objects.using(settings.SLAVE_DB_NAME).filter(
name__in=list(tags_name.keys()), is_online=True,
).values_list('name', 'id')
cities_name = {item[0]: item[1] for item in cities}
map_list = []
for name, c_id in cities_name.items():
tag_id = tags_name.get(name)
if not tag_id: continue
map_list.append(
TagMapCity(
city_id=c_id,
tag_id=tag_id,
)
)
TagMapCity.objects.bulk_create(map_list)
print('Done')
# coding:utf-8
from django.core.management.base import BaseCommand
from gm_types.gaia import TAG_TYPE_ATTR, TAG_V3_TYPE
from agile.models import AttrTag
from agile.models.tag import TagV3MapAttrTag, AttrTagSynonym, TagV3WikiRelation, TagV3, TagSynonym, TagAttrRelation
from utils.execel import ExcelReader
class Command(BaseCommand):
"""
标签新增子属性 python manage.py tag_new_attr_async
"""
def handle(self, *args, **options):
print('START')
# 增加新映射关系
excel = ExcelReader('/tmp/标签导入模板.xlsx')
# 删掉 一级、二级品牌对应的历史数据
attr_tags = AttrTag.objects.filter(aggregate_type__in=[TAG_TYPE_ATTR.BRAND, TAG_TYPE_ATTR.FIRST_BRAND])
_ids = [tag.id for tag in attr_tags]
TagV3MapAttrTag.objects.filter(tag_attr_id__in=_ids).delete()
AttrTagSynonym.objects.filter(tag_attr_id__in=_ids).delete()
TagV3WikiRelation.objects.filter(attr_tag_id__in=_ids).delete()
attr_tags.delete()
# print(excel._excel.get_sheet_names())
brand = excel._excel._sheets[0]
print('-----------开始导入品牌标签-----------')
for row in range(2, brand.max_row+1):
max_column = brand.max_column + 1
row_data = []
for i in range(1, max_column):
cell_value = brand.cell(row=row, column=i).value or u''
print(cell_value)
# cell_value = cell_value.decode('utf-8')
row_data.append(cell_value)
tag_name = str(row_data[0])
synonyms = row_data[1].split(',') if row_data[1] else []
if not any([tag_name, synonyms]):
continue
try:
tag = TagV3.objects.create(
name=tag_name,
tag_type=TAG_V3_TYPE.BRAND,
)
synonym_objects = [
TagSynonym(
name=item,
tag_id=tag.id,
tag_type=TAG_V3_TYPE.BRAND,
) for item in synonyms
]
TagSynonym.objects.bulk_create(synonym_objects)
except:
continue
print('-----------导入品牌标签完成-----------')
print('-----------开始导入一级耗材属性标签-----------')
first_level = excel._excel._sheets[1]
for row in range(2, first_level.max_row+1):
max_column = first_level.max_column + 1
row_data = []
for i in range(1, max_column):
cell_value = first_level.cell(row=row, column=i).value or u''
# cell_value = cell_value.decode('utf-8')
row_data.append(cell_value)
tag_name = str(row_data[0])
synonyms = row_data[1].split(',') if row_data[1] else []
if not any([tag_name, synonyms]):
continue
try:
tag = AttrTag.objects.create(
name=tag_name,
aggregate_type=TAG_TYPE_ATTR.FIRST_BRAND,
)
synonym_objects = [
AttrTagSynonym(
name=item,
tag_attr_id=tag.id,
) for item in synonyms
]
AttrTagSynonym.objects.bulk_create(synonym_objects)
except:
continue
print('-----------导入一级耗材属性标签完成-----------')
print('-----------开始导入二级耗材属性标签-----------')
second_level = excel._excel._sheets[2]
for row in range(2, second_level.max_row+1):
max_column = second_level.max_column + 1
row_data = []
for i in range(1, max_column):
cell_value = second_level.cell(row=row, column=i).value or u''
# cell_value = cell_value.decode('utf-8')
row_data.append(cell_value)
tag_name = str(row_data[0])
synonyms = row_data[1].split(',') if row_data[1] else []
sub_type = row_data[2]
brand_name = row_data[3]
if not any([tag_name, synonyms]):
continue
try:
tag = AttrTag.objects.create(
name=tag_name,
aggregate_type=TAG_TYPE_ATTR.BRAND,
sub_attr_type=sub_type,
)
synonym_objects = [
AttrTagSynonym(
name=item,
tag_attr_id=tag.id,
) for item in synonyms
]
AttrTagSynonym.objects.bulk_create(synonym_objects)
if brand_name:
names = brand_name.split(',')
tags = TagV3.objects.filter(name__in=names, tag_type=TAG_V3_TYPE.BRAND)
tag_v3_ids = [t.id for t in tags]
if tag_v3_ids:
brand_objects = [
TagV3MapAttrTag(
tag_id=_id,
tag_attr_id=tag.id,
) for _id in tag_v3_ids
]
TagV3MapAttrTag.objects.bulk_create(brand_objects)
except:
continue
print('-----------导入二级耗材属性标签完成-----------')
print('-----------开始导入一级、二级耗材属性标签关系-----------')
relation = excel._excel._sheets[3]
for row in range(2, relation.max_row+1):
max_column = relation.max_column + 1
row_data = []
for i in range(1, max_column):
cell_value = relation.cell(row=row, column=i).value or u''
# cell_value = cell_value.decode('utf-8')
row_data.append(cell_value)
first = row_data[1].encode().decode('utf-8')
second = row_data[0].encode().decode('utf-8')
# print(first)
# print(second)
if not all([first, second]):
continue
related_ids = set()
first_brand = AttrTag.objects.filter(name=first, aggregate_type=TAG_TYPE_ATTR.FIRST_BRAND).first()
second_brand = AttrTag.objects.filter(name=second, aggregate_type=TAG_TYPE_ATTR.BRAND).first()
if not all([first_brand, second_brand]):
continue
related_ids.add((first_brand.id, second_brand.id))
print(related_ids)
related_objects = [
TagAttrRelation(
parent_id=item[0],
child_id=item[1],
) for item in related_ids
]
TagAttrRelation.objects.bulk_create(related_objects)
print('-----------导入一级、二级耗材属性标签关系完成-----------')
print("Done!")
# coding:utf-8
from datetime import datetime
from django.core.management.base import BaseCommand
from agile.models.tag import TagV3
class Command(BaseCommand):
""" 处理重复标签 """
def handle(self, *args, **options):
sql_str = 'select id, name, tag_type, count(name) as cnt from api_tag_3_0 group by name having cnt > 1'
tags = TagV3.objects.raw(sql_str)
for tag in tags:
TagV3.objects.filter(id=tag.id).update(name=tag.name+'1')
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from .agile_tag import (
AgileTag,
AgileTagType,
AgileTagRecommendType,
AgileTagMapping,
AgileTagHeraRecommend,
)
from .tag import TagV3
from .tag import TagExtra
from .tag import TagSynonym
from .tag import TagMapOldTag
from .tag import AttrTag
from .tag import AttrTagSynonym
from .tag import TagCategory
from .tag import TagCategoryMapTag
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import, print_function
from django.db import models
from django.utils import timezone
from gm_types.gaia import (
AGILE_TAG_TYPE,
AGILE_TAG_CREATE_TYPE,
AGILE_TAG_STYLE,
AGILE_TAG_RECOMMEND_TYPE,
AGILE_TAG_ATTRIBUTE,
AGILE_TAG_HERA_RECOMMEND_TAB_TYPE,
)
from api.models.tag import Tag as OldTag
class BaseModel(models.Model):
class Meta:
abstract = True
is_online = models.BooleanField(verbose_name=u"是否有效", default=True)
create_time = models.DateTimeField(verbose_name=u'创建时间', auto_now_add=True)
update_time = models.DateTimeField(verbose_name=u'更新时间', auto_now=True)
class AgileTag(BaseModel):
class Meta:
verbose_name = u'新标签'
db_table = 'api_agile_tag'
name = models.CharField(verbose_name=u'新标签名字', max_length=128, null=False, unique=True, default='')
description = models.TextField(verbose_name=u'描述', default='')
create_tag_type = models.CharField(
verbose_name=u"标签创建类型", max_length=3, choices=AGILE_TAG_CREATE_TYPE, default=AGILE_TAG_CREATE_TYPE.OPERATOR)
style = models.CharField(
verbose_name=u"标签样式", max_length=3, choices=AGILE_TAG_STYLE, default=AGILE_TAG_STYLE.UNDEFINED)
attribute = models.CharField(verbose_name=u"标签属性", max_length=3, choices=AGILE_TAG_ATTRIBUTE, default=AGILE_TAG_ATTRIBUTE.NULL)
topic_recommend_sort = models.IntegerField(verbose_name=u'帖子推荐排序', default=9999)
class AgileTagType(BaseModel):
class Meta:
verbose_name = u'新标签类型(可多选)'
db_table = 'api_agile_tag_type'
agile_tag_id = models.IntegerField(verbose_name=u'新标签', db_index=True)
agile_tag_type = models.CharField(
verbose_name=u"标签类型", max_length=3, choices=AGILE_TAG_TYPE, default=AGILE_TAG_TYPE.UNDEFINED)
class AgileTagRecommendType(BaseModel):
class Meta:
verbose_name = u'新标签推荐类型(可多选)'
db_table = 'api_agile_tag_recommend_type'
agile_tag_id = models.IntegerField(verbose_name=u'新标签', db_index=True)
agile_tag_type = models.CharField(
verbose_name=u"标签推荐类型", max_length=3, choices=AGILE_TAG_RECOMMEND_TYPE)
class AgileTagMapping(BaseModel):
class Meta:
verbose_name = u'新标签与老标签映射关系(可多选)'
db_table = 'api_agile_tag_mapping'
agile_tag_id = models.IntegerField(verbose_name=u'新标签', db_index=True)
old_tag_id = models.IntegerField(verbose_name=u'老标签', db_index=True)
class AgileTagHeraRecommend(BaseModel):
class Meta:
verbose_name = u'hera后台推荐新标签'
db_table = 'api_agile_tag_hera_recommend'
unique_together = ('agile_recommend_type', 'agile_tab_type')
agile_recommend_type = models.CharField(verbose_name=u"内容范围(标签推荐类型)", max_length=11, choices=AGILE_TAG_RECOMMEND_TYPE)
agile_tab_type = models.CharField(verbose_name=u"类型(TAB按钮类型)", max_length=11, choices=AGILE_TAG_HERA_RECOMMEND_TAB_TYPE)
agile_tag_sort_ids = models.TextField(verbose_name=u'配置的新标签有序列表,json字符串', default="")
This diff is collapsed.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from .agile_tag import AgileTagService
from .agile_tag_type import AgileTagTypeService
from .agile_tag_mapping import AgileTagMappingTagService
from .agile_tag_polymer import AgileTagRelationPolymerService
from .agile_tag_recommend_type import AgileTagRecommendTypeService
from .agile_tag_hera_recommend import AgileTagHeraRecommendService
from .tag_v3_service import (
TagV3Service,
TagV3Control,
)
# -*- coding: utf-8 -*-
from django.db import IntegrityError
from django.db.models import Q
from django.conf import settings
from gm_types.error import ERROR
from gm_types.gaia import AGILE_TAG_CREATE_TYPE, AGILE_TAG_STYLE
from agile.models.agile_tag import AgileTag
from rpc.tool.error_code import gen
class AgileTagService(object):
model = AgileTag
_base_query = Q(is_online=True)
@classmethod
def create(cls, name=None, description='', order=9999,
create_tag_type=AGILE_TAG_CREATE_TYPE.CUSTOM, style=AGILE_TAG_STYLE.UNDEFINED):
if not name:
return gen(ERROR.AGILE_TAG_NAME_ERR)
data = {
'name': name,
'description': description,
'topic_recommend_sort': order,
'create_tag_type': create_tag_type,
'style': style,
}
try:
agile_tag = cls.model.objects.create(**data)
except IntegrityError:
return gen(ERROR.AGILE_TAG_NAME_EXIST)
return {
'tag_id': agile_tag.id,
'name': agile_tag.name
}
@classmethod
def tag_obj_to_dict(cls, obj, simple=True):
_style = obj.style
_data = {
"id": obj.id,
"name": obj.name,
"style": _style,
"style_image_url": settings.AGILE_STYLE.get(_style, ''),
"attribute": obj.attribute, # 标签属性
}
if not simple:
_data.update({
'description': obj.description,
'order': obj.topic_recommend_sort,
'create_tag_type': obj.create_tag_type,
})
return _data
@classmethod
def tag_queryset_to_dict(cls, queryset=None, simple=True):
result = []
for item in queryset.iterator():
result.append(cls.tag_obj_to_dict(item, simple=simple))
return {'result': result}
@classmethod
def get_tag_by_ids(cls, agile_ids, simple=True):
query = cls._base_query & Q(id__in=agile_ids)
queryset = cls.model.objects.filter(query)
return cls.tag_queryset_to_dict(queryset, simple=simple)
@classmethod
def get_hot_agile_tags_by_ids(cls, agile_ids, simple=True, start_num=0, offset=15):
"""
获取 热门标签
:param agile_ids:
:param start_num:
:param offset:
:param simple:
:param show_style: 展示标签 样式
:return:
"""
query = cls._base_query & Q(id__in=agile_ids)
agile_tags = cls.model.objects.filter(query).order_by(
'topic_recommend_sort', '-id')[start_num: start_num+offset]
agile_dic = cls.tag_queryset_to_dict(agile_tags, simple=simple)
return agile_dic
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
from django.db.models import Q
from agile.models.agile_tag import AgileTagHeraRecommend
class AgileTagHeraRecommendService(object):
model = AgileTagHeraRecommend
_base_query = Q(is_online=True)
@classmethod
def get_hera_recommend_agile_tag_ids(cls, recommend_type, tab_type, start_num=0, count=15):
"""
获取推荐标签
:param recommend_type:
:param tab_type:
:param start_num:
:param count:
:return:
"""
filter_query = cls._base_query & Q(
agile_recommend_type=recommend_type,
agile_tab_type=tab_type
)
agile_tag_ids = []
_agile_tag_sort_ids = cls.model.objects.filter(filter_query).values_list("agile_tag_sort_ids", flat=True).last()
if _agile_tag_sort_ids:
agile_tag_ids = json.loads(_agile_tag_sort_ids)[start_num: start_num + count]
return agile_tag_ids
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from collections import defaultdict
from django.db import IntegrityError
from django.db.models import Q
from django.conf import settings
from gm_types.error import ERROR
from api.models import Tag
from agile.models.agile_tag import AgileTagMapping, AgileTag
class AgileTagMappingTagService(object):
model = AgileTagMapping
_base_query = Q(is_online=True)
@classmethod
def get_mapping_tags_by_agile_tag_ids(cls, agile_tag_ids, only_need_old_tag_ids=False):
"""
获取所有映射的老标签数据
if only_need_old_tag_ids:
return {new_tag_id: [old_tag_id1, old_tag_id2]}
else
return {
new_tag_id : [
{
"id": 1,
"name": "标签名",
"tag_type": 标签类型,
"recommend_type": 推荐类型,
},
]
}
:param agile_tag_ids:
:param only_need_old_tag_ids: 仅需要老标签id
:return:
"""
result = {}
filter_query = cls._base_query & Q(agile_tag_id__in=agile_tag_ids)
mapping_tags = cls.model.objects.filter(filter_query).values("agile_tag_id", "old_tag_id")
if mapping_tags:
result = defaultdict(list)
if only_need_old_tag_ids:
old_tags_info_dic = {}
else:
_old_tag_ids = set(map(lambda item: item["old_tag_id"], mapping_tags))
old_tags_info = Tag.objects.filter(
pk__in=_old_tag_ids,
is_online=True
).values("id", "name", "tag_type", "recommend_type")
old_tags_info_dic = {
tag_info["id"]: dict(tag_info) for tag_info in old_tags_info
}
for mapping_tag in mapping_tags:
if only_need_old_tag_ids:
_info = mapping_tag["old_tag_id"]
else:
_info = old_tags_info_dic.get(mapping_tag["old_tag_id"], {})
if _info:
result[str(mapping_tag["agile_tag_id"])].append(_info)
return dict(result)
@classmethod
def get_mapping_tags_by_old_tag_ids(cls, old_tag_ids):
"""
通过老标签获取对应的新标签
:param old_tag_ids:
:return: {old_tag_id: [new_tag_id1, new_tag_id2]}
"""
result = {}
filter_query = cls._base_query & Q(old_tag_id__in=old_tag_ids)
mapping_tags = cls.model.objects.filter(filter_query).values("agile_tag_id", "old_tag_id")
if mapping_tags:
result = defaultdict(list)
for mapping_tag in mapping_tags:
result[str(mapping_tag["old_tag_id"])].append(mapping_tag["agile_tag_id"])
return dict(result)
@classmethod
def get_mapping_tags_tuple_by_old_tag_ids(cls, old_tag_ids):
"""
通过老标签获取对应的新标签
:param old_tag_ids:
:return: [(new_tag_id1,new_tag_id1_name), (new_tag_id2,new_tag_id2_name)]}
"""
filter_query = cls._base_query & Q(old_tag_id__in=old_tag_ids)
agile_tag_ids = cls.model.objects.filter(filter_query).values_list('agile_tag_id', flat=True)
if not agile_tag_ids:
return list()
res = AgileTag.objects.filter(id__in=agile_tag_ids).values_list('id', 'name')
# print res[0]
return res
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from collections import defaultdict
from django.db.models import Q
from polymer.models import AgileTagRelationPolymer
class AgileTagRelationPolymerService(object):
model = AgileTagRelationPolymer
_base_query = Q(is_online=True)
@classmethod
def create(cls, agile_tag_id, polymer_id):
if not all([agile_tag_id, polymer_id]):
return
cls.model.objects.update_or_create(
agile_tag_id=agile_tag_id,
polymer_id=polymer_id,
defaults={"is_online": True},
)
@classmethod
def get_polymer_id_by_agile_tag_ids(cls, agile_tag_ids):
"""
获取新标签关联的聚合页
:param agile_tag_ids:
:return: {agile_tag_id: polymer_id1,}
"""
result = {}
filter_query = cls._base_query & Q(agile_tag_id__in=agile_tag_ids)
relation_polymers = cls.model.objects.filter(filter_query).values("agile_tag_id", "polymer_id")
if relation_polymers:
result = defaultdict(int)
for relation_polymer in relation_polymers:
result[relation_polymer["agile_tag_id"]] = relation_polymer["polymer_id"]
return dict(result)
# -*- coding: utf-8 -*-
from collections import defaultdict
from django.db.models import Q
from gm_types.error import ERROR
from gm_types.gaia import AGILE_TAG_RECOMMEND_TYPE
from agile.models.agile_tag import AgileTagRecommendType
from rpc.tool.error_code import gen
class AgileTagRecommendTypeService(object):
model = AgileTagRecommendType
_base_query = Q(is_online=True)
@classmethod
def create(cls, agile_tag_id, agile_recommend_types):
"""
新标签推荐类型创建
:param agile_tag_id:
:param agile_recommend_types: list
:return:
"""
if not all([agile_tag_id, agile_recommend_types]):
return
recommend_type_list = []
for _type in agile_recommend_types:
agile_type = cls.model(
agile_tag_id=agile_tag_id,
agile_tag_type=_type
)
recommend_type_list.append(agile_type)
cls.model.objects.bulk_create(recommend_type_list)
return {'id': agile_tag_id}
@classmethod
def get_recommend_type_info(cls, agile_ids):
"""
获取标签的推荐类型
:param agile_ids:
:return:
"""
result = {}
if not agile_ids:
return result
query = cls._base_query & Q(agile_tag_id__in=set(agile_ids))
recommend_types = cls.model.objects.filter(query).values('agile_tag_id', 'agile_tag_type')
if recommend_types:
result = defaultdict(list)
for recommend_type in recommend_types.iterator():
result[recommend_type['agile_tag_id']].append(recommend_type["agile_tag_type"])
return result
@classmethod
def get_agile_tag_ids_by_recommend_type(cls,
agile_tag_ids,
recommend_type=AGILE_TAG_RECOMMEND_TYPE.TRACTATE):
"""
根据推荐类型 获取标签id
:param agile_tag_ids:
:param recommend_type: 推荐类型
:return:
"""
result = []
if not agile_tag_ids:
return result
agile_ids = list(cls.model.objects.filter(
agile_tag_type=recommend_type, agile_tag_id__in=agile_tag_ids
).values_list('agile_tag_id', flat=True))
return agile_ids
# -*- coding: utf-8 -*-
from collections import defaultdict
from django.db.models import Q
from gm_types.error import ERROR
from gm_types.gaia import AGILE_TAG_TYPE
from agile.models.agile_tag import AgileTagType
from rpc.tool.error_code import gen
class AgileTagTypeService(object):
_base_query = Q(is_online=True)
model = AgileTagType
@classmethod
def create(cls, agile_tag_id, agile_tag_types=[AGILE_TAG_TYPE.UNDEFINED]):
"""
标签 与 类型关联 manytomany
:param agile_tag_id:
:param agile_tag_types: list
:return:
"""
if not all([agile_tag_id, agile_tag_types]):
return
agile_type_list = []
for _type in agile_tag_types:
agile_type = cls.model(
agile_tag_id=agile_tag_id,
agile_tag_type=_type
)
agile_type_list.append(agile_type)
cls.model.objects.bulk_create(agile_type_list)
@classmethod
def get_agile_types(cls, agile_ids):
"""
获取新标签的类型
:param agile_ids: list
:return:
"""
result = {}
if not agile_ids:
return result
query = cls._base_query & Q(agile_tag_id__in=set(agile_ids))
agile_tags_type = cls.model.objects.filter(query).values('agile_tag_id', 'agile_tag_type')
if agile_tags_type:
result = defaultdict(list)
for _agile_type in agile_tags_type.iterator():
result[_agile_type["agile_tag_id"]].append(_agile_type["agile_tag_type"])
return dict(result)
@classmethod
def get_agile_ids_by_agile_type(cls, agile_type='', start_num=0, offset=15):
"""
通过类型获取标签id
:param agile_type: agile_type为空时获取所有热门标签
:param start_num:
:param offset:
:return:
"""
query = cls._base_query
if agile_type:
query = query & Q(agile_tag_type=agile_type)
agile_ids = list(cls.model.objects.filter(query).values_list('agile_tag_id', flat=True))
return {'ids': agile_ids}
This diff is collapsed.
This diff is collapsed.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from .agile_tag import *
from .tag_v3 import *
# -*- coding: utf-8 -*-
import json
from django.conf import settings
from gm_types.error import ERROR
from gm_types.gaia import (
AGILE_TAG_RECOMMEND_TYPE,
AGILE_TAG_HERA_RECOMMEND_TAB_TYPE,
)
from rpc.decorators import bind, bind_context
from agile.services import (
AgileTagService,
AgileTagTypeService,
AgileTagMappingTagService,
AgileTagRecommendTypeService,
AgileTagRelationPolymerService,
AgileTagHeraRecommendService,
TagV3Service
)
from rpc.tool.error_code import gen
from .common import AgileTagFormat
from rpc.cache import old_new_tag_mapping_cache
@bind('api/agile/create')
def agile_tag_create(name, description='', order=None, create_tag_type=None, style=None,
agile_tag_types=None, agile_recommend_types=None, relation_polymer_id=None):
"""
新标签创建
:param name:
:param description:
:param order:
:param create_tag_type:
:param style:
:param agile_tag_types:
:param agile_recommend_types:
:return:
"""
if not name:
return gen(ERROR.AGILE_TAG_NAME_ERR)
agile = AgileTagService.create(name=name)
agile_id = agile.get('tag_id')
AgileTagTypeService.create(agile_id)
# 需要建立关联聚合页的话
if relation_polymer_id:
AgileTagRelationPolymerService.create(
agile_tag_id=agile_id,
polymer_id=relation_polymer_id
)
return agile
@bind('api/agile_tags/by_type')
def get_agile_by_type(agile_type, recommend_type=AGILE_TAG_RECOMMEND_TYPE.TRACTATE, show_style=False, start_num=0, offset=15):
"""
根据标签类型 获取热门标签
:param agile_type:
:param recommend_type: 标签推荐范围
:param show_style:
:param start_num:
:param offset:
:return:
"""
result = {}
if not agile_type:
agile_type = AGILE_TAG_HERA_RECOMMEND_TAB_TYPE.ALL
# 获取有序的推荐标签
_recommend_agile_tag_ids = AgileTagHeraRecommendService.get_hera_recommend_agile_tag_ids(
recommend_type=recommend_type,
tab_type=agile_type,
start_num=start_num,
count=offset
)
_tag_list = (
AgileTagService.get_tag_by_ids(
agile_ids=_recommend_agile_tag_ids
) or {}).get("result", [])
tags = sorted(_tag_list, key=lambda item: _recommend_agile_tag_ids.index(item.get("id", 0)))
result.update({'agile_tags': tags})
return {'result': result}
@bind("api/agile_tag/info_by_ids")
def get_agile_tag_by_ids(agile_tag_ids, simple=True, only_need_old_tag_ids=True, return_dic=False):
"""
通过标签id获取数据
:param agile_tag_ids:
:param simple: 基本数据
:param only_need_old_tag_ids:仅需要老标签id
:param return_dic: 返回的数据结构 True dict False []
:return:
"""
result = {} if return_dic else []
if agile_tag_ids:
assert len(agile_tag_ids) <= settings.COUNT_LIMIT, 'too many agile_tag_ids'
agile_tag_info_dic = AgileTagFormat.agile_tags_info_format(
agile_tag_ids,
simple=simple,
only_need_old_tag_ids=only_need_old_tag_ids
)
# 数据结构返回控制
if return_dic:
result = agile_tag_info_dic
else:
result = list(agile_tag_info_dic.values())
return result
@bind("api/agile_tag/get_mapping_old_tag_ids_by_ids")
def get_mapping_old_tag_ids_by_agile_tag_ids(agile_tag_ids, only_need_old_tag_ids=True):
"""
仅获取新标签映射的老标签
:param agile_tag_ids:
:param only_need_old_tag_ids:
:return:
"""
result = {
"tag_mapping": {}
}
if agile_tag_ids:
assert len(agile_tag_ids) <= settings.COUNT_LIMIT, 'too many agile_tag_ids'
# 新标签,标签映射老标签数据
result["tag_mapping"] = AgileTagMappingTagService.get_mapping_tags_by_agile_tag_ids(
agile_tag_ids,
only_need_old_tag_ids=only_need_old_tag_ids
)
return result
@bind("api/agile_tag/get_agile_tags_by_old_tag_ids")
def get_agile_tags_by_old_tag_ids(old_tag_ids):
"""
通过老标签,获取对应的新标签
:param old_tag_ids:
:param only_need_new_tag_ids:
:return:
"""
result = {
"tag_mapping": {}
}
if old_tag_ids:
assert len(old_tag_ids) <= settings.COUNT_LIMIT, 'too many old_tag_ids'
result["tag_mapping"] = AgileTagMappingTagService.get_mapping_tags_by_old_tag_ids(old_tag_ids)
return result
@bind("api/agile_tag/tuple_new_tags")
def get_agile_tags_tuple_by_old_tag_ids(old_tag_ids):
result = get_cache_data(old_tag_ids, True)
return result
@bind("api/agile_tag/cache")
def get_cache_agile_data(old_tag_ids):
"""
Get hash list cache mapping data
:param old_tag_ids:
:return:
"""
result = get_cache_data(old_tag_ids)
return result
def get_cache_data(old_tag_ids, use_tuple=False):
result = list()
if old_tag_ids is None:
return result
if not isinstance(old_tag_ids, list):
return result
cache_name = settings.TAT_MAPPING_HASH_NAME
pipe = old_new_tag_mapping_cache.pipeline()
for key in old_tag_ids:
pipe.hget(cache_name, key)
data = pipe.execute()
for item in data:
if item:
_info = json.loads(item)
if use_tuple:
result.append((_info.get('id'), _info.get('name')))
else:
result.append(_info)
return result
@bind("api/agile_tag/section_tags")
def get_section_tags():
section_tags = TagV3Service.get_section_tags()
return {"section_tags": section_tags}
@bind("api/agile_tag/improve_appeals")
def get_improve_appeals(section_tag_ids):
improve_appeals = TagV3Service.get_improve_appeals(section_tag_ids)
return {"improve_appeals": improve_appeals}
@bind("api/agile_tag/suit_projects")
def get_suit_projects(improve_appeal_ids):
suit_projects = TagV3Service.get_suit_projects(improve_appeal_ids)
return {"suit_projects": suit_projects}
@bind("api/agile_tag/get_section_tag")
def get_section_tag(section_tag_id):
return TagV3Service.section_tag_data(section_tag_id)
@bind("api/agile_tag/get_improve_appeal")
def get_improve_appeal(improve_appeal_id):
return TagV3Service.improve_appeal_data(improve_appeal_id)
@bind("api/agile_tag/get_suit_project")
def get_suit_project(suit_project_id):
return TagV3Service.suit_project_data(suit_project_id)
@bind("api/agile_tag/get_old_attr_tag")
def gets_old_attr_tag(aggregate_type, offset=0, size=100):
""" 仅用于数据迁移 PS:业务不可用 """
from agile.models import AttrTag
attrs = AttrTag.objects.filter(aggregate_type=aggregate_type)[offset: size]
return {str(item.id): item.name for item in attrs}
@bind("api/agile_tag/get_new_tag")
def gets_new_tag(tag_type, offset=0, size=100):
""" 仅用于数据迁移 PS:业务不可用 """
from agile.models import TagV3
tags = TagV3.objects.filter(tag_type=tag_type)[offset: size]
return {str(item.id): item.name for item in tags}
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from agile.services import (
AgileTagService,
AgileTagTypeService,
AgileTagMappingTagService,
AgileTagRecommendTypeService,
AgileTagRelationPolymerService,
)
class AgileTagFormat(object):
@classmethod
def agile_tags_info_format(cls, agile_tag_ids, simple=True, only_need_old_tag_ids=True):
"""
新标签数据拼接转换
:param agile_tag_ids:
:param simple:
:param only_need_old_tag_ids:
:return:
"""
# 新标签,标签基本数据
_agile_tags_dic = AgileTagService.get_tag_by_ids(agile_tag_ids, simple=simple)
# 新标签,标签类型数据
_agile_tags_type_dic = AgileTagTypeService.get_agile_types(agile_tag_ids)
# 新标签,标签推荐类型数据
_agile_tags_recommend_type_dic = AgileTagRecommendTypeService.get_recommend_type_info(agile_tag_ids)
if simple: # 如果只是需要简单数据的话
_agile_tags_mapping_dic = {}
_agile_tags_polymer = {}
else:
# 新标签,标签映射老标签数据
_agile_tags_mapping_dic = AgileTagMappingTagService.get_mapping_tags_by_agile_tag_ids(
agile_tag_ids,
only_need_old_tag_ids=only_need_old_tag_ids
)
# 获取对应的聚合页数据
_agile_tags_polymer = AgileTagRelationPolymerService.get_polymer_id_by_agile_tag_ids(
agile_tag_ids
)
# 数据组装
_agile_tags = _agile_tags_dic.get("result", [])
_agile_tags_dic = {}
for agile_tag in _agile_tags:
_agile_tag_id = agile_tag.get("id", 0)
if _agile_tag_id:
agile_tag.update({
"tags_type": _agile_tags_type_dic.get(_agile_tag_id, []),
"recommends_type": _agile_tags_recommend_type_dic.get(_agile_tag_id, []),
"mapping_old_tag_ids": [], # 仅有id
"mapping_old_tags_info": [], # 详细数据
"polymer_id": _agile_tags_polymer.get(_agile_tag_id, 0) # 关联的聚合页id
})
if only_need_old_tag_ids:
agile_tag.update({
"mapping_old_tag_ids": _agile_tags_mapping_dic.get(str(_agile_tag_id), []),
})
else:
agile_tag.update({
"mapping_old_tags_info": _agile_tags_mapping_dic.get(str(_agile_tag_id), [])
})
_agile_tags_dic[str(_agile_tag_id)] = agile_tag
return _agile_tags_dic
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from django.conf import settings
from django.db.models import Q
from gm_types.error import ERROR
from gm_types.gaia import (
TAG_TYPE_ATTR,
TAG_V3_TYPE,
)
from agile.models import (
TagV3,
)
from agile.services import (
TagV3Service,
TagV3Control,
)
from agile.services.tag import get_diary_ids_for_ai_tab
from rpc.decorators import (
bind,
bind_context,
)
from rpc.tool.dict_mixin import to_dict
from rpc.tool.error_code import gen
MAX_LENGTH = 100
@bind("api/tag_v3/related_tags_info_by_id_on_second_appeal")
def list_related_tags_info_by_id_on_second_appeal(tag_id):
"""
通过标签id,获取基本信息
:param tag_ids:
:return: {} dict
"""
second_appeal_attrs = TagV3Service.list_second_appeal_attrs([tag_id])
tags = TagV3Service.list_tags_by_attrs([attr.id for attrs in second_appeal_attrs.values() for attr in attrs])
return list(tags.values())
@bind("api/tag_v3/get_tags_by_attr_tag_ids")
def get_tags_by_attr_tag_ids(attr_tag_ids):
"""
通过属性标签获取普通标签
:param attr_tag_ids:属性标签id列表
:return: list
"""
tags = TagV3Service.list_normal_tags_by_attrs(attr_tag_ids)
return list(tags.values())
@bind("api/tag_v3/info_by_ids")
def get_tag_v3_info_by_ids(tag_ids):
"""
通过标签id,获取基本信息
:param tag_ids:
:return: {} dict
"""
return TagV3Service.get_tags_v3_by_ids(tag_ids)
@bind("api/tag_v3/attr_info_by_ids")
def get_attr_tag_infos_by_ids(attr_ids, attr_types=None):
"""
backend 无调用
通过属性标签ID,获取属性标签信息
:param attr_ids:
:param attr_types: [] 默认为空,属性类型列表
:return:
"""
return TagV3Service.get_attr_tag_info_by_attr_ids(attr_ids, attr_types=attr_types)
@bind("api/tag_v3/get_map_new_tag_by_old_ids")
def get_map_new_tag_by_old_ids(old_tag_ids):
"""
通过老标签id,获取映射的新标签数据
:param old_tag_ids:
:return: {} dict
"""
return TagV3Service.get_tag_v3_info_by_old_ids(old_tag_ids)
@bind("api/tag_v3/get_bodypart_tags")
def get_bodypart_tags(need_app_display=False):
"""level one tags, and sub_bodypart_items tags.
:param need_app_display: 需要app外显属性的标签,默认是全部标签
:return:
"""
return TagV3Service.get_bodypart_tags(need_app_display=need_app_display)
@bind("api/tag_v3/get_closure_tags")
def get_closure_tags(tag_ids, is_online_only=True, only_need_app_display=False):
"""
获取标签的所有父类标签,注意:这块未保留关联关系
:param tag_ids:
:param is_online_only:
:param only_need_app_display: 仅需要app外显的
:return:
"""
tags = TagV3Service.get_objs_by_query_and_order(
model_set=TagV3,
query=Q(pk__in=tag_ids)
)
closure_tags = TagV3Control.get_ancestors(
initial_set=tags,
exclude_init=False,
is_online_only=is_online_only,
only_need_app_display=only_need_app_display
)
return [to_dict(t, fields=('id', 'name', 'tag_type')) for t in closure_tags]
@bind("api/tag_v3/get_ai_tab_unclean_diary_ids")
def get_ai_tab_unclean_diary_ids(last_diary_id=None, max_diary_id=None):
""""根据strategy_id获取未来清洗的日记id。
Return:
{
unclean_diary: [
1, 2, 3, 4, 5....
]
}
"""
unclean_diary = get_diary_ids_for_ai_tab(last_diary_id, max_diary_id)
return {"unclean_diary": list(unclean_diary)}
@bind("api/tag_v3/list_group_by_tags")
def list_group_by_tags(tag_ids):
""""根据标签ID列表获取标签大组信息。
Return:
{
tag_id: [
{
"id": category.id,
"name": category.name,
}
]
}
"""
tag_category_map = TagV3Service.get_category_by_tags(tag_ids)
result = {}
for k, v in tag_category_map.items():
result[str(k)] = v
return result
@bind('api/tag_v3_category')
def get_tag_v3_category(category_ids):
"""根据大组id获取大组信息"""
tag_category_map = TagV3Service.get_category_by_ids(category_ids)
result = {}
for k, v in tag_category_map.items():
result[str(k)] = v
return result
@bind('api/tag_v3/gets_relation_tag')
def gets_relation_tag(tag_ids=None, tag_names=None, tag_type=None):
"""获取指定标签的相关标签"""
service = TagV3Service()
return service.gets_relation_tag(tag_ids=tag_ids, tag_names=tag_names, tag_type=tag_type)
@bind('api/tag_v3/gets_info')
def gets_info(tag_ids=None, tag_names=None, tag_type=None):
"""获取指定标签的信息"""
service = TagV3Service()
return service.gets_info(tag_ids=tag_ids, tag_names=tag_names, tag_type=tag_type)
@bind('api/tag_v3/gets_synonym_or_homoionym')
def gets_synonym_or_homoionym(tag_ids=None, tag_names=None, tag_type=None, get_synonym=True):
"""获取指定标签的近义词或同义词"""
service = TagV3Service()
return service.gets_synonym_or_homoionym(
tag_ids=tag_ids, tag_names=tag_names, tag_type=tag_type, get_synonym=get_synonym)
@bind('api/tag_v3/gets_tag_info_by_ids')
def gets_tag_info_by_ids(tag_ids=None, tag_type=None):
"""获取指定标签信息"""
service = TagV3Service()
return service.gets_tag_info_by_ids(tag_ids=tag_ids, tag_type=tag_type)
@bind('api/tag_v3/gets_tag_normal')
def gets_tag_normal():
"""获取新标签---项目标签"""
tag_list = []
tags = TagV3.objects.filter(tag_type=TAG_V3_TYPE.NORMAL, is_online=True)
for tag in tags:
tag_list.append({
'id': tag.id,
'name': tag.name,
'tag_type': tag.tag_type,
})
return {'tagv3_normal': tag_list}
@bind('api/tag_v3/by_type')
def get_tag_ids_by_type(tag_type):
if tag_type not in TAG_V3_TYPE:
return {}
ids = TagV3Service.get_tag_ids_by_type(tag_type)
return {'tag_v3_ids': ids}
# coding=utf8
from __future__ import unicode_literals, absolute_import, print_function
from .gaia_api import *
# coding=utf-8
from gm_types.gaia import QUESTION_ORDER_TYPE, USER_TYPE
from api.models import Province, Zone
from api.tasks.user_related_tasks import get_sleep_user
from api.tool.user_tool import get_auth_type_by_userid, get_user_type_ids
from rpc.decorators import bind
from rpc.decorators import list_interface
from search.utils.question import filter_question
from social import SocialInfo
from statistic import const_strings
@bind('api/question/filter')
@list_interface(offset_name='offset', limit_name='size')
def api_filter_question(offset=0, size=5, province_id=None, sort_type=QUESTION_ORDER_TYPE.DEFAULT, filters={}, sort_params=None):
"""
question filter.
:param province_id:
:param offset:
:param size:
:param sort_type:
:param filters:
:param sort_params:
:return:
"""
if province_id:
try:
p = Province.objects.get(id=province_id)
if p.tag:
filters['area_tag_id'] = p.tag.id
except Province.DoesNotExist:
pass
return filter_question(offset=offset, size=size, sort_type=sort_type, filters=filters, sort_params=sort_params)
@bind('api/user/is_following')
def is_following(cuid, uid):
return SocialInfo(cuid).is_following_user(uid)
@bind('api/user/auth_type')
def get_user_auth_type(uid):
"""
get user auth type
:param uid:
:return:
"""
return get_auth_type_by_userid(uid)
@bind('api/users/user_type')
def get_user_auth_type(uids):
"""
get users user type
:param user_ids:
:return:
"""
users_type = get_user_type_ids(uids)
result = {}
for uid, user_type in users_type.items():
if user_type['hospital_id']:
user_type["user_type"] = USER_TYPE.OFFICER
elif user_type['doctor_id']:
user_type["user_type"] = USER_TYPE.EXPERT
else:
user_type["user_type"] = USER_TYPE.USER
result[uid] = user_type
return result
@bind('api/user/get_sleep_user')
def _get_sleep_user(number):
user_extras = get_sleep_user(number)
return [user_extra.user.id for user_extra in user_extras]
@bind('api/province/list')
def province_list(**kwargs):
"""
:param kwargs:
:return:
"""
queryset = Province.objects.all()
display_in_filter = kwargs.get('display_in_filter')
if display_in_filter is not None:
queryset = queryset.filter(display_in_filter=display_in_filter)
provinces = [{'id': p.id, 'name': p.name} for p in queryset]
provinces.insert(0, {'id': const_strings.NATIONWIDE, 'name': u'全国'})
return provinces
@bind('api/zone/list')
def zone_list(pks):
"""
zone list.
:return:
"""
return [{'id': zone.id} for zone in Zone.objects.filter(pk__in=pks)]
from .answer import *
\ No newline at end of file
This diff is collapsed.
# coding=utf8
from __future__ import unicode_literals, absolute_import, print_function
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from _celery import app as celery_app
from api.signals import *
from django.contrib import admin
# Register your models here.
# -*- coding: utf-8 -*-
from django.db import models
from gm_types.gaia import REQUEST_SOURCE
from rpc.api_control import request_source
class RequestSourceManager(models.Manager):
"""马甲包配置项"""
def get_queryset(self):
req_source = request_source.__dict__.get('req_source')
if req_source:
return super(RequestSourceManager, self).get_queryset().filter(
req_source=req_source
)
else:
return super(RequestSourceManager, self).get_queryset().filter()
class RequestSourceModel(models.Model):
objects = RequestSourceManager()
class Meta:
abstract = True
req_source = models.CharField(u'请求来源', max_length=32, choices=REQUEST_SOURCE.choices, default=REQUEST_SOURCE.GEMGMEI)
# -*- coding: utf-8 -*-
from message.views.message import internal_message_send
from message.utils.push_service import UserPushService
\ No newline at end of file
File added
# coding=utf8
from __future__ import unicode_literals, absolute_import, print_function
This diff is collapsed.
# coding=utf8
from __future__ import unicode_literals, absolute_import, print_function
from ..models import TAG_TYPE
from ..models import Tag, TagRelation, dfs_child_closure, dfs_parent_closure
def is_valid_tag_type(tag_type):
o = object()
return TAG_TYPE.getDesc(tag_type, o) is not o
class TagControl(object):
@classmethod
def get_tag(cls, pk):
return Tag.objects.get(pk=pk)
@classmethod
def add_tag(cls, name, tag_type):
# TODO: 目前到做法语意不明
t, created = Tag.objects.get_or_create(name=name)
if created:
assert is_valid_tag_type(tag_type)
t.tag_type = tag_type
t.save()
return t
@classmethod
def add_relation(cls, parent, child):
TagRelation.add_relation(parent=parent, child=child)
@classmethod
def del_relation(cls, parent, child):
TagRelation.del_relation(parent=parent, child=child)
@classmethod
def get_ancestors(cls, initial_set, exclude_init, tag_type=None, is_online_only=None):
result = dfs_parent_closure(initial_set=initial_set, exclude_init=exclude_init, is_online_only=is_online_only).values()
if tag_type is not None:
assert is_valid_tag_type(tag_type)
result = [tag for tag in result if tag.tag_type == tag_type]
return result
@classmethod
def get_descendants(cls, initial_set, exclude_init, tag_type=None, is_online_only=None):
result = dfs_child_closure(initial_set=initial_set, exclude_init=exclude_init, is_online_only=is_online_only).values()
if tag_type is not None:
assert is_valid_tag_type(tag_type)
result = [tag for tag in result if tag.tag_type == tag_type]
return result
# coding=utf-8
__author__ = 'cheng'
# coding=utf-8
__author__ = 'cheng'
# -*- coding: utf-8 -*-
from django.core.management import BaseCommand
from lasker.models import AwardResult
import datetime
class Command(BaseCommand):
""" Import famous doctor award list from txt to database """
def handle(self, *args, **options):
print("Start Insert AwardResult Data!")
with open("2019_famous_doctor_list.txt") as of:
update_or_create_count = 0
for line in of.readlines():
line_details = line.split()
AwardResult.objects.update_or_create(
laureate_id=line_details[1].decode('utf-8'),
defaults={
'laureate_name': line_details[0].decode('utf-8'),
'laureate_type': int(line_details[5]),
'award_name': line_details[2].decode('utf-8'),
'is_deleted': False,
'online_time': datetime.datetime.strptime(line_details[3], "%Y-%m-%d"),
'offline_time': datetime.datetime.strptime(line_details[4], "%Y-%m-%d"),
'is_special_skin': int(line_details[6])
}
)
update_or_create_count += 1
print("AwardResult Success Insert One Column Data!Index %d" % update_or_create_count)
print("Success!!!, Total %d Column" % update_or_create_count)
# coding: utf-8
# 2020 名医大赏 美购增加标签
from django.core.management import BaseCommand
from api.models import Service, ServiceTag, Tag
from gm_types.gaia import TAG_TYPE
tag2service_ids = {
u'2019-年度优秀私密整形医生': ['5758093', '5758746', '5758756'],
u'2019-年度优秀眼部整形医生': ['5809063', '5809276', '5767521'],
u'2019-年度优秀鼻部整形医生': ['5840468', '5840491', '5864089'],
u'2019-年度优秀脂肪管理医生': ['5823634', '5299163', '5456115'],
u'2019-年度优秀颌面整形机构': ['5815356', '5834997', '5858006'],
u'2019-年度优秀鼻部整形机构': ['5803913', '5860750', '5860771'],
u'2019-年度优秀口碑整形机构': ['5240975', '5832387', '5191770'],
u'2019-年度口碑整形机构': ['5746636', '5746188', '5774732'],
u'2019-年度实力整形机构': ['5822144', '5752820', '5750162'],
u'2019-年度优秀颌面整形医生': ['5798876', '5798887', '5798886'],
u'2019-年度优秀胸部整形机构': ['5773563', '5836484', '5851722'],
u'2019-年度优秀私密整形机构': ['5801676', '5801679', '5801677'],
u'2019-年度人气整形机构': ['5788111', '5788109', '5850825'],
u'2019-年度优秀眼部整形机构': ['5756487', '5798748', '5756488']
}
class Command(BaseCommand):
def handle(self, *args, **options):
for tag_name, service_ids in tag2service_ids.items():
tag = Tag.objects.filter(name=tag_name).first()
if not tag:
tag = Tag()
tag.name = tag_name
tag.tag_type = TAG_TYPE.YUNYING
tag.is_online = 1
tag.banner_url = ""
tag.ordering = 100
tag.is_online = 1
tag.save()
exec_info = list()
for service_id in service_ids:
service_id = int(service_id)
if Service.objects.filter(id=service_id).first():
ServiceTag.objects.update_or_create(service_id=service_id, tag_id=tag.id)
exec_info.append(str(service_id))
if exec_info:
print("成功导入 %s 相关的美购ids %s" % (tag_name, ",".join(exec_info)))
print("SUCCESS")
This diff is collapsed.
# coding=utf-8
from django.core.management import BaseCommand
from api.models import Area
class Command(BaseCommand):
@classmethod
def _save_data(cls, name, num):
a = Area(area_name=name, phone_prefix=num)
a.save()
def handle(self, *args, **kwargs):
self._save_data(u'中国大陆', u'+86')
self._save_data(u'香港', u'+852')
self._save_data(u'台湾', u'+886')
self._save_data(u'韩国', u'+82')
self._save_data(u'日本', u'+81')
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment