消息推送(python),相对路径等

文章背景

做app 消息推送

自己写sdk的缘由

有些只支持Python2 有些支持Python3 兼容,不支持3 的如果不太复杂就自己根据官方api文档写一个请求的,如果复杂就在直接用sdk ,这样只能用Python3 调用Python2。在很多代码中在Python2 环境中是不报错的但是在Python3中是报错的, 这就牵扯到Python3 Python2 中引入模块的问题;

python2,3 引入模块的相对 绝对路径等

在对这两种分布清楚的情况下,最好使用绝对路径,弄清楚的情况也最好使用绝对路径

Python中package 和普通包之间的区别

  • package 文件夹中多了一个init .py 的文件 ,有了这个文件Python就认为这个文件夹是一个package, package 是可以引入的但是普通文件夹是不可以的

  • init.py 文件是空的,只是用来告诉你 当前文件夹是个package.里面也可以添加代码,这些代码会在import 这个包的时候运行

  • 所以,请你再你要import 文件所在的文件夹下面是有init.py 的(除非它在sys.path中的某个文件夹下面)

导入路径

from package.subpackage1 import foo1 

package 是在根目录下的文件夹, 使用绝对路径导入

python的-m参数官方说法是:
Searches sys.path for the named module and runs the corresponding .py file as a script.

在下面的例子中,加上-m参数后,所运行的.py文件便会识别其顶层的package

创建完main.py之后,cd到项目的根目录,运行

python -m package

即可实现直接运行main.py,即直接运行了package这个包

如果你想直接运行package内的某个.py文件,比如foo1,则:

python -m package.subpackage1.foo1

当然,你要确保foo1中存在判断其是否是入口函数的逻辑,如下:

if __name__ == "__main__":
    speak()

python2 缺省为相对路径,python3缺省为绝对路径导入
Python2 绝对路径导入

from __future__ import absolute_import

python2缺省会搜索上一级目录、上上级目录
解决方案

import platform
pver=platform.python_version()
pversion= int(pver.split('.')[0])
try:
 if pversion==2:
     print(1)
     from .A import aa
 else:
   print(2)
   from A import aa
except:
  print(3)
  from A import aa

异常处理

try:
  from .A import aa
  print(12)
except:
  print(22)
  from A import aa

总言之 要使用绝对路径,并且绝对路径和相对路径不要混用
http://blog.sina.com.cn/s/blog_5d0adef001017yq8.html
上面的这个不错
当我改友盟推送的 Python实例代码就的时候就修改的是成Python3 路径都改为了绝对路径

目前还没有解决遇到最大困难

当提供的sdk 比较复杂的时候 还是Python2 而项目使用的是python3 的时候 使用Python3 调用Python2的代码,这样就要维持两个环境。传递参数的时候会遇到这样的问题

  • 参数有空格的问题
  • 有汉字的时候(在windos系统上面这个问题解决不了,浪费了我一整天来解决编码问题,还是不可以的)

友盟推送

鉴于上面遇到的困难,再结合项目需求就把这个 python示例给重写为Python3 的。这里顺便说下,示例代码是有错误的,body里面添加数据的时候只能添加第一条数据,而且里面代码不够规范,有些代码的后面竟然有; (分号),这是我第一次遇见,如果从开始学习Python的时候看到这样的代码的时候肯定对对我照成影响的。
这里写图片描述

这是我项目的目录结构
调用的代码

import json
from push.umeng.umessage.pushclient import PushClient
from push.umeng.umessage.iospush import *
from push.umeng.umessage.androidpush import *
from push.umeng.umessage.errorcodes import UMPushError, APIServerErrorCode
from push.umeng.umessage.iosnotification import IOSNotification

#注意andorid和ios是不同的appkey和appMasterSecret。 在不同需求下换成各自的appkey。
appKey = "xxx"
appMasterSecret = "xxx"
# deviceToken = "xxx"

class UmengSend(object):
    #android
    @staticmethod
    def sendAndroidUnicast(deviceToken,  custom, ticker="", title="", text=""):
        # 必填项
        unicast = AndroidUnicast(appKey, appMasterSecret)
        unicast.setDeviceToken(deviceToken)
        unicast.setTicker(ticker)
        unicast.setTitle(title)
        unicast.setText(text)
        unicast.goAppAfterOpen()
        # unicast.setDisplayType(AndroidNotification.DisplayType.notification)
        unicast.setDisplayType(AndroidNotification.DisplayType.message)
        unicast.setCustomField(custom)
        # unicast.setTestMode()
        pushClient = PushClient()
        ret = pushClient.send(unicast)
        data = UmengSend.printResult(ret)
        return data

    @staticmethod
    def printResult(ret):
        response_data = dict()
        response_data["http status code"] = ret.status_code
        # print("http status code: %s" % ret.status_code)

        if ret.text != "":
            ret_json = json.loads(ret.text)
            if ret_json["ret"] == IOSNotification.CONSTR_STATUS_SUCCESS:
                if 'msg_id' in ret_json['data']:
                    response_data["msgId"] = ret_json['data']['msg_id']
                    # print("msgId: %s" % ret_json['data']['msg_id'])
                if 'task_id' in ret_json['data']:
                    response_data["task_id"] = ret_json['data']['task_id']
                    # print("task_id: %s" % ret_json['data']['task_id'])
            elif ret_json["ret"] == IOSNotification.CONSTR_STATUS_FAIL:
                errorcode = int(ret_json["data"]["error_code"])
                response_data["errorcode"] = errorcode
                response_data["detail"] = APIServerErrorCode.errorMessage(errorcode)

                # print("error Code: %s, detail: %s" % (errorcode, APIServerErrorCode.errorMessage(errorcode)))

            return response_data


if __name__ == '__main__':
    deviceToken = "xxx"
    title = "nihao"
    ticker = "成功了"
    text = "我是杨"
    custom = "我是custom"
    UmengSend.sendAndroidUnicast(deviceToken, custom, ticker=ticker, title=title, text=text)

去官网获取deviceToken appkey,appMasterSecret 需要的值等,看文档来选择自己需需要的推送样式和模板

个推推送

个推推送有点复杂只支持Python2 的sdk ,这里想了一个办法用来调用Python2 的方法,但是这样遇到了两个现在没有解决的问题,空格, 还有编码问题
getui.py

# -*- coding: utf-8 -*-
import sys
import json
from igetui.igt_message import IGtAppMessage
from igetui.template.igt_link_template import LinkTemplate
from igt_push import IGeTui
from igt_push import *
from igetui.template import *
from igetui.template.igt_base_template import *
from igetui.template.igt_transmission_template import *
from igetui.template.igt_link_template import *
from igetui.template.igt_notification_template import *
from igetui.template.igt_notypopload_template import *
from igetui.igt_message import *
from igetui.igt_target import *
from igetui.template import *


from sys import argv

if sys.version < '3':
    reload(sys)
    sys.setdefaultencoding('utf-8')

HOST = 'http://sdk.open.api.igexin.com/apiex.htm'
APPKEY = "xxx"
APPID = "xxx"
MASTERSECRET = "xxx"
# CID = "xxx"
HOST = 'http://sdk.open.api.igexin.com/apiex.htm'


def get_message(content):
    """获取消息"""
    message = IGtSingleMessage()
    message.isOffline = True
    message.offlineExpireTime = 1000 * 3600 * 12
    message.data = get_template(content)
    message.pushNetWorkType = 1
    return message


def get_template(content):
    """获得模板"""
    template = TransmissionTemplate()
    template.transmissionType = 1
    template.appId = APPID
    template.appKey = APPKEY
    template.transmissionContent = content
    return template


def get_target(cid):
    """获得推送目标"""
    target = Target()
    target.appId = APPID
    target.clientId = cid
    return target


def pushMessageToSingle(cid, content):
    """进行推送"""

    print content
    push = IGeTui(None, APPKEY, MASTERSECRET, True)
    message = get_message(content)
    target = get_target(cid)
    try:
        ret = push.pushMessageToSingle(message, target)
        print ret
    except RequestException, e:
        # print e
        requstId = e.getRequestId()
        ret = push.pushMessageToSingle(message, target, requstId)
        print ret

print "jijijii"
import chardet
cid = argv[1]
# encoding_dict = chardet.detect(argv[2])

# content = argv[2].decode("ISO-8859-1").encode("utf8").decode("utf8")
# content = json.loads(argv[2])
# content = content.get("a").decode("ascii").encode("utf8").decode("utf8")

content = argv[2]
print content

pushMessageToSingle(cid, content)

# import chardet

getui_send.py 用于执行系统的命令来执行的Python2 代码

# coding: utf-8
import os
import json
import platform


the_platform = platform.system()
if the_platform == "Windows":
    PYTHON2PATH = r"C:\Python27\python.exe"
elif the_platform == "Linux":
    PYTHON2PATH = r"/bin/python"
current_path = os.path.dirname(os.path.abspath(__file__)) + "/"
NAME = current_path + "getui_send"


def execute_python2(cid, content, python2path=PYTHON2PATH, name=NAME):
    # print content
    cmd = python2path + " " + name + ".py " + cid + " " + content
    print(cmd)
    command = os.popen(cmd)
    # print(command)
    try:
        print("in try")
        # print(command.read())
        result = command.readlines()
    except Exception as ex:
        print("in except")
        print(ex)
        result = list()
    return result


if __name__ == "__main__":
    pass
    cid = "xxx"
    # # cid = "f3263437f5ef90fe8ff9fdeda6c0c3e4"
    # # content = u"'hello2 word'"
    # content = "\"hello word好\""
    # content = str("hellowordwww好erere各个".encode("utf8"))
    # content = u"hello好"
    # content = "hellowordwww好".encode("utf8").decode("utf8")
    content = "hellowordwww好"
    # content = repr("hellowordwww好".encode("utf8"))

    # content = "hellowordwww好"
    # dic_test = dict()
    # dic_test["a"] = content

    print(content)

    result = execute_python2(cid, content)
    print(type(result))

    print(result)

想到一个问题,在有很多文件的时候

在有很多文件的时候,并且哪些都是2中环境才可以的话那就每个要用代码调用才能说是在Python2 的环境的。 在个推中出现不能使用中文还使用了很多别的文件,相当于只用是一个自己写的一个主要文件去调用Python2 环境 ,起的的还是Python 3 的问题,这里面的问题还是没有解决。最好的办法是把 本地的sdk自己改写为3的环境不然就才难受了,各种你想不到的bug就会出现。

别跑麻烦,

咨询了大神,上面这段话是有问题的,只要这个文件使用Python2的环境,那么这个文件使用的文件引入的文件都是使用的python2 的环境

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值