186 lines
5.4 KiB
Python
186 lines
5.4 KiB
Python
# 使用次数统计脚本
|
|
import os
|
|
import platform
|
|
import threading
|
|
import uuid
|
|
from functools import wraps
|
|
from typing import Any, Callable, Tuple
|
|
from urllib.parse import quote_plus
|
|
from .config import currentVersion
|
|
import sys
|
|
|
|
import requests
|
|
|
|
from .log import logger, try_except
|
|
|
|
# ---------------- 需要自行调整的配置 --------------------------------
|
|
# Google Analytics 统计代码的UA,在 https://analytics.google.com/ 申请新的ua,具体流程可百度
|
|
GA_TRACKING_ID = "UA-212229431-1"
|
|
# ua名称,自定义
|
|
USER_AGENT = "DNFCalculating"
|
|
# 应用名称,自定义
|
|
APP_NAME = "DNFCalculating"
|
|
# 网址域名,自定义
|
|
DOCUMENT_HOSTNAME = "dnf-calculating.com"
|
|
# 版本号,可以使用现在的版本变量
|
|
APP_VERSION = currentVersion
|
|
|
|
# ---------------- 枚举定义 --------------------------------
|
|
GA_API_URL = "https://www.google-analytics.com/collect"
|
|
|
|
GA_REPORT_TYPE_EVENT = "event"
|
|
GA_REPORT_TYPE_PAGE_VIEW = "page_view"
|
|
|
|
# ---------------- utils --------------------------------
|
|
|
|
|
|
def async_call(cb, *args, **params):
|
|
threading.Thread(target=cb, args=args, kwargs=params, daemon=True).start()
|
|
|
|
|
|
def get_cid():
|
|
return "{}-{}".format(platform.node(), uuid.getnode())
|
|
|
|
|
|
def get_resolution() -> str:
|
|
width, height = get_screen_size()
|
|
return f"{width}x{height}"
|
|
|
|
|
|
def get_screen_size() -> Tuple[int, int]:
|
|
"""
|
|
:return: 屏幕宽度和高度
|
|
"""
|
|
if not is_windows():
|
|
return 1920, 1080
|
|
|
|
import win32api
|
|
width, height = win32api.GetSystemMetrics(0), win32api.GetSystemMetrics(1)
|
|
return width, height
|
|
|
|
|
|
def is_windows() -> bool:
|
|
return platform.system() == "Windows"
|
|
|
|
|
|
# ---------------- 接口封装 --------------------------------
|
|
|
|
|
|
def increase_counter(name: Any = "",
|
|
ga_type=GA_REPORT_TYPE_EVENT,
|
|
ga_category="",
|
|
ga_misc_params: dict = None):
|
|
if "main.py" in sys.argv[0]:
|
|
return
|
|
name = str(name)
|
|
|
|
if name == "":
|
|
raise AssertionError("increase_counter name not set")
|
|
|
|
async_call(increase_counter_sync_google_analytics, name, ga_type,
|
|
ga_category, ga_misc_params)
|
|
|
|
|
|
@try_except(show_exception_info=False)
|
|
def increase_counter_sync_google_analytics(name: str, ga_type: str,
|
|
ga_category: str,
|
|
ga_misc_params: dict):
|
|
# 上报谷歌分析 v3
|
|
logger.debug(f"report to google analytics v3, name = {name}")
|
|
|
|
if ga_type == GA_REPORT_TYPE_EVENT:
|
|
if ga_category == "":
|
|
# 如果ga_category为空,则尝试从name中解析,假设name中以/分隔的第一个部分作为ga_category
|
|
parts = name.split('/', 1)
|
|
if len(parts) == 2:
|
|
ga_category, name = parts
|
|
else:
|
|
ga_category = "counter"
|
|
track_event(ga_category, name, ga_misc_params)
|
|
elif ga_type == GA_REPORT_TYPE_PAGE_VIEW:
|
|
track_page(name, ga_misc_params)
|
|
else:
|
|
logger.error(f"unknow ga_type={ga_type}")
|
|
|
|
|
|
# ---------------- Google Analytics 上报脚本 --------------------------------
|
|
|
|
# note: 查看数据地址 https://analytics.google.com/analytics/web/#/
|
|
# note: 当发现上报失败时,可以将打印的post body复制到 https://ga-dev-tools.web.app/hit-builder/ 进行校验,看是否缺了参数,或者有参数不符合格式
|
|
# note: 参数文档 https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
|
|
|
|
headers = {
|
|
"user-agent": USER_AGENT,
|
|
}
|
|
|
|
common_data = {
|
|
'v': '1', # API Version.
|
|
'tid': GA_TRACKING_ID, # Tracking ID / Property ID.
|
|
'cid': get_cid(
|
|
), # Anonymous Client Identifier. Ideally, this should be a UUID that is associated with particular user, device, or browser instance.
|
|
'ua': USER_AGENT,
|
|
'an': APP_NAME,
|
|
'av': APP_VERSION,
|
|
'ds': 'app',
|
|
'sr': get_resolution(),
|
|
}
|
|
|
|
|
|
@try_except(show_exception_info=False)
|
|
def track_event(category: str,
|
|
action: str,
|
|
label=None,
|
|
value=0,
|
|
ga_misc_params: dict = None):
|
|
if ga_misc_params is None:
|
|
ga_misc_params = {}
|
|
|
|
data = {
|
|
**common_data,
|
|
't': 'event', # Event hit type.
|
|
'ec': category, # Event category.
|
|
'ea': action, # Event action.
|
|
'el': label, # Event label.
|
|
'ev': value, # Event value, must be an integer
|
|
**ga_misc_params, # 透传的一些额外参数
|
|
}
|
|
|
|
res = requests.post(GA_API_URL, data=data, headers=headers, timeout=10)
|
|
logger.debug(f"request body = {res.request.body}")
|
|
|
|
|
|
@try_except(show_exception_info=False)
|
|
def track_page(page: str, ga_misc_params: dict = None):
|
|
if ga_misc_params is None:
|
|
ga_misc_params = {}
|
|
|
|
page = quote_plus(page)
|
|
data = {
|
|
**common_data,
|
|
't': 'pageview', # Event hit type.
|
|
'dh': DOCUMENT_HOSTNAME, # Document hostname.
|
|
'dp': page, # Page.
|
|
'dt': "", # Title.
|
|
**ga_misc_params, # 透传的一些额外参数
|
|
}
|
|
|
|
res = requests.post(GA_API_URL, data=data, timeout=10)
|
|
logger.debug(f"request body = {res.request.body}")
|
|
|
|
|
|
# ---------------- test --------------------------------
|
|
|
|
|
|
def test():
|
|
increase_counter("test_event", GA_REPORT_TYPE_EVENT)
|
|
increase_counter("test_page_view", GA_REPORT_TYPE_PAGE_VIEW)
|
|
|
|
# track_event("example", "test")
|
|
track_page("/example/test_quote")
|
|
|
|
os.system("PAUSE")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
test()
|