Parcourir la source

okr_automatic_v1

罗俊辉 il y a 1 an
Parent
commit
23928d57d0
9 fichiers modifiés avec 725 ajouts et 0 suppressions
  1. 67 0
      app.py
  2. 465 0
      config.py
  3. 19 0
      create_map.py
  4. 28 0
      feishu_insert.py
  5. 0 0
      functions/__init__.py
  6. 97 0
      functions/feishu.py
  7. 14 0
      functions/get_yesterday_data.py
  8. 0 0
      functions/mysql.py
  9. 35 0
      functions/odps_function.py

+ 67 - 0
app.py

@@ -0,0 +1,67 @@
+from functions.odps_function import OdpsFunction
+from functions.feishu import Feishu
+from config import column_map, alg_map, yesterday_columns
+from functions.get_yesterday_data import find_yesterday_data
+
+
+def read_odps_data():
+    """
+    从 odps 读取数据
+    :return:
+    """
+    o = OdpsFunction()
+    sql = """select * from loghubods.okr_kd where dt = '20240225';"""
+    data = o.select(sql)
+    return data
+
+
+def process_data(data_obj):
+    """
+    把对象数据转化为 list
+    :param data_obj:
+    :return:
+    """
+    keys = ["c{}".format(i) for i in range(1, 350)]
+    temp = {}
+    for key in keys:
+        try:
+            temp[key] = int(data_obj[key])
+        except:
+            temp[key] = data_obj[key]
+    # 获取昨天的数据并且更新到 temp 中
+    for column in yesterday_columns:
+        if temp[column_map[column]] != "-" or temp[column_map[column]] != "--":
+            yes_d = find_yesterday_data(column)
+            if type(yes_d) != str:
+                temp[column_map[column]] = yes_d
+    result = []
+    for key in temp:
+        if alg_map.get(key):
+            obj = {
+                "type": "formula",
+                "text": alg_map[key],
+                "number_setting": {"format": "percentage", "decimal_count": 2},
+            }
+            result.append(obj)
+        else:
+            result.append(temp[key])
+    return result
+
+
+def insert_into_feishu(data_list):
+    """
+    插入飞书表
+    :param data_list:
+    :return:
+    """
+    F = Feishu("C1Qrsa4HWh6bzEtv7aocrFlAnad")
+    F.insert_value(sheet_id="Zi7oYW", values=[data_list[:100]], ranges="A5:CV5")
+    F.insert_value(sheet_id="Zi7oYW", values=[data_list[100:200]], ranges="CW5:GR5")
+    F.insert_value(sheet_id="Zi7oYW", values=[data_list[200:300]], ranges="GS5:KN5")
+    F.insert_value(sheet_id="Zi7oYW", values=[data_list[300:]], ranges="KO5:MK5")
+
+
+if __name__ == "__main__":
+    data = read_odps_data()
+    result_list = process_data(data)
+    insert_into_feishu(result_list)

+ 465 - 0
config.py

@@ -0,0 +1,465 @@
+# 对照表
+import json
+
+column_map = {
+    "A": "c1",
+    "B": "c2",
+    "C": "c3",
+    "D": "c4",
+    "E": "c5",
+    "F": "c6",
+    "G": "c7",
+    "H": "c8",
+    "I": "c9",
+    "J": "c10",
+    "K": "c11",
+    "L": "c12",
+    "M": "c13",
+    "N": "c14",
+    "O": "c15",
+    "P": "c16",
+    "Q": "c17",
+    "R": "c18",
+    "S": "c19",
+    "T": "c20",
+    "U": "c21",
+    "V": "c22",
+    "W": "c23",
+    "X": "c24",
+    "Y": "c25",
+    "Z": "c26",
+    "AA": "c27",
+    "AB": "c28",
+    "AC": "c29",
+    "AD": "c30",
+    "AE": "c31",
+    "AF": "c32",
+    "AG": "c33",
+    "AH": "c34",
+    "AI": "c35",
+    "AJ": "c36",
+    "AK": "c37",
+    "AL": "c38",
+    "AM": "c39",
+    "AN": "c40",
+    "AO": "c41",
+    "AP": "c42",
+    "AQ": "c43",
+    "AR": "c44",
+    "AS": "c45",
+    "AT": "c46",
+    "AU": "c47",
+    "AV": "c48",
+    "AW": "c49",
+    "AX": "c50",
+    "AY": "c51",
+    "AZ": "c52",
+    "BA": "c53",
+    "BB": "c54",
+    "BC": "c55",
+    "BD": "c56",
+    "BE": "c57",
+    "BF": "c58",
+    "BG": "c59",
+    "BH": "c60",
+    "BI": "c61",
+    "BJ": "c62",
+    "BK": "c63",
+    "BL": "c64",
+    "BM": "c65",
+    "BN": "c66",
+    "BO": "c67",
+    "BP": "c68",
+    "BQ": "c69",
+    "BR": "c70",
+    "BS": "c71",
+    "BT": "c72",
+    "BU": "c73",
+    "BV": "c74",
+    "BW": "c75",
+    "BX": "c76",
+    "BY": "c77",
+    "BZ": "c78",
+    "CA": "c79",
+    "CB": "c80",
+    "CC": "c81",
+    "CD": "c82",
+    "CE": "c83",
+    "CF": "c84",
+    "CG": "c85",
+    "CH": "c86",
+    "CI": "c87",
+    "CJ": "c88",
+    "CK": "c89",
+    "CL": "c90",
+    "CM": "c91",
+    "CN": "c92",
+    "CO": "c93",
+    "CP": "c94",
+    "CQ": "c95",
+    "CR": "c96",
+    "CS": "c97",
+    "CT": "c98",
+    "CU": "c99",
+    "CV": "c100",
+    "CW": "c101",
+    "CX": "c102",
+    "CY": "c103",
+    "CZ": "c104",
+    "DA": "c105",
+    "DB": "c106",
+    "DC": "c107",
+    "DD": "c108",
+    "DE": "c109",
+    "DF": "c110",
+    "DG": "c111",
+    "DH": "c112",
+    "DI": "c113",
+    "DJ": "c114",
+    "DK": "c115",
+    "DL": "c116",
+    "DM": "c117",
+    "DN": "c118",
+    "DO": "c119",
+    "DP": "c120",
+    "DQ": "c121",
+    "DR": "c122",
+    "DS": "c123",
+    "DT": "c124",
+    "DU": "c125",
+    "DV": "c126",
+    "DW": "c127",
+    "DX": "c128",
+    "DY": "c129",
+    "DZ": "c130",
+    "EA": "c131",
+    "EB": "c132",
+    "EC": "c133",
+    "ED": "c134",
+    "EE": "c135",
+    "EF": "c136",
+    "EG": "c137",
+    "EH": "c138",
+    "EI": "c139",
+    "EJ": "c140",
+    "EK": "c141",
+    "EL": "c142",
+    "EM": "c143",
+    "EN": "c144",
+    "EO": "c145",
+    "EP": "c146",
+    "EQ": "c147",
+    "ER": "c148",
+    "ES": "c149",
+    "ET": "c150",
+    "EU": "c151",
+    "EV": "c152",
+    "EW": "c153",
+    "EX": "c154",
+    "EY": "c155",
+    "EZ": "c156",
+    "FA": "c157",
+    "FB": "c158",
+    "FC": "c159",
+    "FD": "c160",
+    "FE": "c161",
+    "FF": "c162",
+    "FG": "c163",
+    "FH": "c164",
+    "FI": "c165",
+    "FJ": "c166",
+    "FK": "c167",
+    "FL": "c168",
+    "FM": "c169",
+    "FN": "c170",
+    "FO": "c171",
+    "FP": "c172",
+    "FQ": "c173",
+    "FR": "c174",
+    "FS": "c175",
+    "FT": "c176",
+    "FU": "c177",
+    "FV": "c178",
+    "FW": "c179",
+    "FX": "c180",
+    "FY": "c181",
+    "FZ": "c182",
+    "GA": "c183",
+    "GB": "c184",
+    "GC": "c185",
+    "GD": "c186",
+    "GE": "c187",
+    "GF": "c188",
+    "GG": "c189",
+    "GH": "c190",
+    "GI": "c191",
+    "GJ": "c192",
+    "GK": "c193",
+    "GL": "c194",
+    "GM": "c195",
+    "GN": "c196",
+    "GO": "c197",
+    "GP": "c198",
+    "GQ": "c199",
+    "GR": "c200",
+    "GS": "c201",
+    "GT": "c202",
+    "GU": "c203",
+    "GV": "c204",
+    "GW": "c205",
+    "GX": "c206",
+    "GY": "c207",
+    "GZ": "c208",
+    "HA": "c209",
+    "HB": "c210",
+    "HC": "c211",
+    "HD": "c212",
+    "HE": "c213",
+    "HF": "c214",
+    "HG": "c215",
+    "HH": "c216",
+    "HI": "c217",
+    "HJ": "c218",
+    "HK": "c219",
+    "HL": "c220",
+    "HM": "c221",
+    "HN": "c222",
+    "HO": "c223",
+    "HP": "c224",
+    "HQ": "c225",
+    "HR": "c226",
+    "HS": "c227",
+    "HT": "c228",
+    "HU": "c229",
+    "HV": "c230",
+    "HW": "c231",
+    "HX": "c232",
+    "HY": "c233",
+    "HZ": "c234",
+    "IA": "c235",
+    "IB": "c236",
+    "IC": "c237",
+    "ID": "c238",
+    "IE": "c239",
+    "IF": "c240",
+    "IG": "c241",
+    "IH": "c242",
+    "II": "c243",
+    "IJ": "c244",
+    "IK": "c245",
+    "IL": "c246",
+    "IM": "c247",
+    "IN": "c248",
+    "IO": "c249",
+    "IP": "c250",
+    "IQ": "c251",
+    "IR": "c252",
+    "IS": "c253",
+    "IT": "c254",
+    "IU": "c255",
+    "IV": "c256",
+    "IW": "c257",
+    "IX": "c258",
+    "IY": "c259",
+    "IZ": "c260",
+    "JA": "c261",
+    "JB": "c262",
+    "JC": "c263",
+    "JD": "c264",
+    "JE": "c265",
+    "JF": "c266",
+    "JG": "c267",
+    "JH": "c268",
+    "JI": "c269",
+    "JJ": "c270",
+    "JK": "c271",
+    "JL": "c272",
+    "JM": "c273",
+    "JN": "c274",
+    "JO": "c275",
+    "JP": "c276",
+    "JQ": "c277",
+    "JR": "c278",
+    "JS": "c279",
+    "JT": "c280",
+    "JU": "c281",
+    "JV": "c282",
+    "JW": "c283",
+    "JX": "c284",
+    "JY": "c285",
+    "JZ": "c286",
+    "KA": "c287",
+    "KB": "c288",
+    "KC": "c289",
+    "KD": "c290",
+    "KE": "c291",
+    "KF": "c292",
+    "KG": "c293",
+    "KH": "c294",
+    "KI": "c295",
+    "KJ": "c296",
+    "KK": "c297",
+    "KL": "c298",
+    "KM": "c299",
+    "KN": "c300",
+    "KO": "c301",
+    "KP": "c302",
+    "KQ": "c303",
+    "KR": "c304",
+    "KS": "c305",
+    "KT": "c306",
+    "KU": "c307",
+    "KV": "c308",
+    "KW": "c309",
+    "KX": "c310",
+    "KY": "c311",
+    "KZ": "c312",
+    "LA": "c313",
+    "LB": "c314",
+    "LC": "c315",
+    "LD": "c316",
+    "LE": "c317",
+    "LF": "c318",
+    "LG": "c319",
+    "LH": "c320",
+    "LI": "c321",
+    "LJ": "c322",
+    "LK": "c323",
+    "LL": "c324",
+    "LM": "c325",
+    "LN": "c326",
+    "LO": "c327",
+    "LP": "c328",
+    "LQ": "c329",
+    "LR": "c330",
+    "LS": "c331",
+    "LT": "c332",
+    "LU": "c333",
+    "LV": "c334",
+    "LW": "c335",
+    "LX": "c336",
+    "LY": "c337",
+    "LZ": "c338",
+    "MA": "c339",
+    "MB": "c340",
+    "MC": "c341",
+    "MD": "c342",
+    "ME": "c343",
+    "MF": "c344",
+    "MG": "c345",
+    "MH": "c346",
+    "MI": "c347",
+    "MJ": "c348",
+    "MK": "c349",
+}
+
+# 需要使用昨天的数据的表
+yesterday_columns = {
+    "F",
+    "H",
+    "J",
+    "AC",
+    "BD",
+    "CE",
+    "DF",
+    "EG",
+    "FH",
+    "GI",
+    "HJ",
+    "IK",
+    "JL",
+    "LJ",
+    "LS",
+    "LT",
+    "MA",
+    "MB",
+}
+
+# 公式表
+alg_map = {
+    "c3": "=SUM(AL5,BM5,CN5,DO5,EP5,FQ5,GR5,HS5,IT5,JU5,LJ5,LR5,LS5,ML5,MW5)",
+    "c4": "=C5/B5",
+    "c5": "=(LU5+LB5)/B5",
+    "c6": "=(AC5+BD5+CE5+DF5+EG5+FH5+GI5+HJ5+IK5+JL5)/B5",
+    "c7": "=SUM(AL5,BM5,CN5,DO5,EP5,FQ5,GR5,HS5,IT5,JU5)",
+    "c8": "=LJ5+LS5",
+    "c9": "=LR5+ML5+MW5",
+    "c10": "=MA5",
+    "c11": "=E5+F5",
+    "c14": "=Y5+AL5",
+    "c15": "=N5/L5",
+    "c24": "=Y5/T5",
+    "c25": "=(P5/1000)*MA5",
+    "c30": "=AB5/AC5",
+    "c33": "=AC5/L5",
+    "c41": "=AZ5+BM5",
+    "c42": "=AO5/AM5",
+    "c51": "=AZ5/AU5",
+    "c52": "=(AQ5/1000)*MA5",
+    "c57": "=BC5/BD5",
+    "c60": "=BD5/AM5",
+    "c67": "=(BN5-BN7)/BN7",
+    "c68": "=CA5+CN5",
+    "c69": "=BP5/BN5",
+    "c78": "=CA5/BV5",
+    "c79": "=(BR5/1000)*MA5",
+    "c84": "=CD5/CE5",
+    "c87": "=CE5/BN5",
+    "c95": "=DB5+DO5",
+    "c96": "=CQ5/CO5",
+    "c105": "=DB5/CW5",
+    "c106": "=(CS5/1000)*MA5",
+    "c111": "=DE5/DF5",
+    "c114": "=DF5/CO5",
+    "c122": "=EC5+EP5",
+    "c123": "=DR5/DP5",
+    "c132": "=EC5/DX5",
+    "c133": "=(DT5/1000)*MA5",
+    "c138": "=EF5/EG5",
+    "c141": "=EG5/DP5",
+    "c149": "=FD5+FQ5",
+    "c150": "=ES5/EQ5",
+    "c165": "=FG5/FH5",
+    "c168": "=FH5/EQ5",
+    "c176": "=GE5+GR5",
+    "c177": "=FT5/FR5",
+    "c186": "=GE5/FZ5",
+    "c187": "=(FV5/1000)*MA5",
+    "c192": "=GH5/GI5",
+    "c195": "=GI5/FR5",
+    "c203": "=HF5+HS5",
+    "c204": "=GU5/GS5",
+    "c213": "=HF5/HA5",
+    "c214": "=(GW5/1000)*MA5",
+    "c219": "=HI5/HJ5",
+    "c222": "=HJ5/GS5",
+    "c230": "=IG5+IT5",
+    "c231": "=HV5/HT5",
+    "c240": "=IG5/IB5",
+    "c241": "=(HX5/1000)*MA5",
+    "c246": "=IJ5/IK5",
+    "c249": "=IK5/HT5",
+    "c257": "=JH5+JU5",
+    "c258": "=IW5/IU5",
+    "c267": "=JH5/JC5",
+    "c268": "=(IY5/1000)*MA5",
+    "c273": "=JK5/JL5",
+    "c276": "=JL5/IU5",
+    "c311": "=LJ5+LR5",
+    "c312": "=KY5/KW5",
+    "c321": "=LJ5/LE5",
+    "c333": "=SUM(Q5,AR5,BS5,CT5,DU5,FW5,GX5,HY5,IZ5)",
+    "c334": "=SUM(P5,AQ5,BR5,CS5,DT5,FV5,GW5,HX5,IY5)",
+    "c335": "=LU5/(LU5+AC5+BD5+CE5+DF5+EG5+FH5+GI5+HJ5+IK5+JL5+LL5)",
+    "c336": "=LS5-(LV5/1000*MC5)",
+    "c337": "=SUM(T5,AU5,BV5,CW5,DX5,FC5,FZ5,HA5,IB5,JC5,LE5)",
+    "c338": "=H5/LY5",
+    "c341": "=(AB5*AI5+BC5*BJ5+CD5*CK5+DE5*DL5+EF5*EM5+FG5*FN5+GH5*GO5+HI5*HP5+IJ5*IQ5+JK5*JR5)/(AB5+BC5+CD5+DE5+EF5+FG5+GH5+HI5+IJ5+JK5)",
+    "c342": "=(MA5-MC5)/MC5",
+}
+
+
+# r = {}
+# for i in alg_map:
+#     r[i] = alg_map[i].replace("6", "5")
+# print(json.dumps(r, ensure_ascii=False, indent=4))

+ 19 - 0
create_map.py

@@ -0,0 +1,19 @@
+# 循环从 65 到 90(包含 90)
+import json
+
+c = []
+for i in range(65, 91):
+    # 将 ASCII 值转换为字符并打印
+    c.append(chr(i))
+w = [i for i in c]
+for i in c:
+    for j in c:
+        w.append("{}{}".format(i, j))
+
+X = w[:349]
+
+obj = {}
+for index, ite in enumerate(X, 1):
+    obj[ite] = "c{}".format(index)
+
+print(json.dumps(obj, ensure_ascii=False, indent=4))

+ 28 - 0
feishu_insert.py

@@ -0,0 +1,28 @@
+import json
+
+from functions.feishu import Feishu
+from config import alg_map
+
+if __name__ == "__main__":
+    F = Feishu("C1Qrsa4HWh6bzEtv7aocrFlAnad")
+    w = F.search_value(sheet_id="jbEcaz", ab="A6:MK6")
+    values = w["data"]["valueRange"]["values"]
+    value_list = values[0]
+    new_list = []
+    for index, item in enumerate(value_list):
+        if alg_map.get("c{}".format(index)):
+            obj = {
+                "type": "formula",
+                "text": alg_map["c{}".format(index)],
+                "number_setting": {"format": "percentage", "decimal_count": 2},
+            }
+            new_list.append(obj)
+        else:
+            new_list.append(item)
+
+    print(json.dumps(new_list, ensure_ascii=False, indent=4))
+    print(len(new_list))
+    F.insert_value(sheet_id="Zi7oYW", values=[new_list[:100]], ranges="A6:CV6")
+    F.insert_value(sheet_id="Zi7oYW", values=[new_list[100:200]], ranges="CW6:GR6")
+    F.insert_value(sheet_id="Zi7oYW", values=[new_list[200:300]], ranges="GS6:KN6")
+    F.insert_value(sheet_id="Zi7oYW", values=[new_list[300:]], ranges="KO6:MK6")

+ 0 - 0
functions/__init__.py


+ 97 - 0
functions/feishu.py

@@ -0,0 +1,97 @@
+"""
+feishu python方法
+"""
+
+import requests
+
+
+def get_app_token():
+    """
+    获取飞书api token
+    :return:
+    """
+    url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/"
+    post_data = {
+        "app_id": "cli_a51114cf8bf8d00c",  # 这里账号密码是发布应用的后台账号及密码
+        "app_secret": "cNoTAqMpsAm7mPBcpCAXFfvOzCNL27fe",
+    }
+    response = requests.request("POST", url=url, data=post_data)
+    tenant_access_token = response.json()["tenant_access_token"]
+    return tenant_access_token
+
+
+class Feishu(object):
+    """
+    feishu Python Object
+    """
+
+    def __init__(self, document_token):
+        self.headers = {"Content-Type": "application/json"}
+        self.document_token = document_token
+
+    def prepend_value(self, sheet_id, ranges, values):
+        """
+        在表的某一个sheet的ranges中插入数据,若该地方存在数据,会自动把已有的数据往下移动,再写如数据
+        :param sheet_id: 飞书表的唯一ID
+        :param ranges: 单元格位置的range, 从左上角到右下角, 两边都是闭区间
+        :param values: 二维数组, 用于填充ranges的空格数组
+        """
+        insert_value_url = "https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{}/values_prepend".format(
+            self.document_token
+        )
+        # print(get_app_token())
+        headers = {
+            "Authorization": "Bearer " + get_app_token(),
+            "contentType": "application/json; charset=utf-8",
+        }
+        body = {
+            "valueRange": {"range": "{}!{}".format(sheet_id, ranges), "values": values}
+        }
+        response = requests.request(
+            "POST", url=insert_value_url, headers=headers, json=body
+        )
+        print(response.json())
+
+    def insert_value(self, sheet_id, ranges, values):
+        """
+        插入数据
+        :param sheet_id:
+        :param ranges:
+        :param values:
+        :return:
+        """
+        insert_value_url = (
+            "https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{}/values".format(
+                self.document_token
+            )
+        )
+        headers = {
+            "Authorization": "Bearer " + get_app_token(),
+            "contentType": "application/json; charset=utf-8",
+        }
+        body = {
+            "valueRange": {"range": "{}!{}".format(sheet_id, ranges), "values": values}
+        }
+        response = requests.request(
+            "PUT", url=insert_value_url, headers=headers, json=body
+        )
+        print(response.json())
+
+    def search_value(self, sheet_id, ab):
+        """
+        搜索
+        :param sheet_id:
+        :param ab:
+        :return:
+        """
+        ranges = "{}!{}".format(sheet_id, ab)
+        # print(ranges)
+        search_url = "https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{}/values/{}".format(
+            self.document_token, ranges
+        )
+        headers = {
+            "Authorization": "Bearer " + get_app_token(),
+            "contentType": "application/json; charset=utf-8",
+        }
+        response = requests.request("GET", url=search_url, headers=headers)
+        return response.json()

+ 14 - 0
functions/get_yesterday_data.py

@@ -0,0 +1,14 @@
+from functions.feishu import Feishu
+
+
+def find_yesterday_data(column_index):
+    """
+    根据 column_index来获取前一天的数据
+    :param column_index:
+    :return:
+    """
+    F = Feishu("C1Qrsa4HWh6bzEtv7aocrFlAnad")
+    data = F.search_value(
+        sheet_id="Zi7oYW", ab="{}6:{}6".format(column_index, column_index)
+    )
+    return data["data"]["valueRange"]["values"][0][0]

+ 0 - 0
functions/mysql.py


+ 35 - 0
functions/odps_function.py

@@ -0,0 +1,35 @@
+"""
+python odps function
+"""
+
+import os
+
+from odps import ODPS
+
+
+class OdpsFunction(object):
+    """
+    odps function class
+    """
+
+    def __init__(self):
+        self.endpoint = "http://service.cn.maxcompute.aliyun.com/api"
+        self.access_id = "LTAIWYUujJAm7CbH"
+        self.access_key = "RfSjdiWwED1sGFlsjXv0DlfTnZTG1P"
+        self.project = "loghubods"
+
+        self.od = ODPS(
+            access_id=self.access_id,
+            secret_access_key=self.access_key,
+            endpoint=self.endpoint,
+            project=self.project,
+        )
+
+    def select(self, sql):
+        """
+        :param sql: 查询语句
+        :return: odps_obj{}
+        """
+        with self.od.execute_sql(sql).open_reader() as reader:
+            for record in reader:
+                return record