예제 #1
0
파일: zapi.py 프로젝트: wszg5/studyGit
def slotService():
    reqs = request.json

    action = request.json['action']
    if 'id' in request.json:
        id = request.json['id']

    serial = request.json['serial']
    type = request.json['type']

    if 'remark' in request.json:
        remark = request.json['remark']
    else:
        remark = "Backed";

    if 'page' in reqs:
        page = reqs['page']
    else:
        page = 1;

    if not action:
        return jsonify({'success': False, 'msg': u'paramter action is missed'})

    if not serial:
        return jsonify({'success': False, 'msg': u'paramter serial is missed'})

    slot = Slot(serial, type)
    if action == "save":
        if remark == "":
            remark = "BackUp"
        slot.backup(id, remark)
        return jsonify({'success': True, 'msg': u'Save slot success'})

    if action == "restore":
        slot.restore(id)
        return jsonify({'success': True, 'msg': u'Restore slot success'})

    if action == "clear":
        slot.clear(id)
        return jsonify({'success': True, 'msg': u'Clear slot success'})

    if action == "list":
        result = []
        slots = slot.getSlots()
        if not slots:
            slots = {};
        idFrom = (page - 1)*20 + 1
        idTo = (page-1) * 20 + 20
        for index in range(idFrom, idTo + 1):
            if slots.has_key(str(index)) :
                obj = slots[str(index)]
                obj['empty'] = False;
                obj['id'] = index
            else:
                obj = {'id':index, 'empty': True}
            result.append(obj)

        return jsonify({'slots': result })

    return "-"
예제 #2
0
class InternationqqLogin:
    def __init__(self):
        self.type = 'mobileqqi'
        self.repo = Repo()
        self.codedll = codeDLL()

    def GetUnique(self):
        nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S");  # 生成当前时间
        randomNum = random.randint(0, 1000);  # 生成的随机整数n,其中0<=n<=100
        if randomNum <= 10:
            randomNum = str(00) + str(randomNum);
        uniqueNum = str(nowTime) + str(randomNum);
        return uniqueNum

    def playCode(self, codeImgObj):
        z.toast("非网页视图打码")
        self.scode = smsCode(d.server.adb.device_serial())
        base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, "tmp"))
        if not os.path.isdir(base_dir):
            os.mkdir(base_dir)
        sourcePng = os.path.join(base_dir, "%s_s.png" % (self.GetUnique()))
        codePng = os.path.join(base_dir, "%s_c.png" % (self.GetUnique()))
        icode = imageCode()
        im_id = ""
        for i in range(0, 4):  # 打码循环
            if i > 0:
                icode.reportError(im_id)

            obj = d(resourceId='com.tencent.mobileqqi:id/0', className='android.widget.ImageView')  # 当弹出选择QQ框的时候,定位不到验证码图片
            if not obj.exists:
                return False

            obj = obj.info
            obj = obj['bounds']  # 验证码处的信息
            left = obj["left"]  # 验证码的位置信息
            top = obj['top']
            right = obj['right']
            bottom = obj['bottom']

            d.screenshot(sourcePng)  # 截取整个输入验证码时的屏幕

            img = Image.open(sourcePng)
            box = (left, top, right, bottom)  # left top right bottom
            region = img.crop(box)  # 截取验证码的图片

            img = Image.new('RGBA', (right - left, bottom - top))
            img.paste(region, (0, 0))

            img.save(codePng)

            with open( codePng, 'rb' ) as im:
                codeResult = self.codedll.QQPlayCode( im )
            # im = open(codePng, 'rb')
    #
    #         codeResult = icode.getCode(im, icode.CODE_TYPE_4_NUMBER_CHAR, 60)
    #
    #         code = codeResult["Result"]
    #         im_id = codeResult["Id"]
    #         os.remove(sourcePng)
    #         os.remove(codePng)
    #
    #         z.sleep(3)
    #         z.heartbeat()
    #         codeImgObj.set_text(code)  # 输入获取的验证码
    #
    #         z.sleep(2)
    #         d(description='完成').click()
    #
    #         z.sleep(10)
    #         z.heartbeat()
    #         if codeImgObj.exists:
    #             continue
    #         else:
    #             break
    #     z.sleep(3)
    #     if d(textContains='验证码').exists:
    #         return True
    #     else:
    #         return False

    def login(self, d, args, z, numbers):

        QQNumber = numbers[0]['number']  # 即将登陆的QQ号
        QQPassword = numbers[0]['password']

        z.heartbeat()
        d.server.adb.cmd("shell", "pm clear com.tencent.mobileqqi").communicate()  # 清除缓存
        d.server.adb.cmd("shell", "am start -n com.tencent.mobileqqi/com.tencent.mobileqq.activity.SplashActivity").communicate()  # 拉起来

        z.sleep(5)
        while d(textContains='正在更新数据').exists:
            z.sleep(2)
        z.sleep(15)
        z.heartbeat()

        d.dump(compressed=False)
        d(className='android.widget.EditText', index=0).click()  # 1918697054----xiake1234.  QQNumber
        z.input(QQNumber)

        z.sleep(1)
        d(resourceId='com.tencent.mobileqqi:id/password').click()  # Bn2kJq5l     QQPassword
        z.input(QQPassword)

        print('QQ号:%s,QQ密码:%s' % (QQNumber, QQPassword))

        z.sleep(1)
        d.dump(compressed=False)
        d(resourceId='com.tencent.mobileqqi:id/login').click()  # 点击登陆按钮

        z.sleep(2)
        flag = 0
        while not d(text='输入验证码').exists and flag < 3:
            flag += 1
            z.sleep(10)
            z.heartbeat()

        not_detection_robot = d(resourceId='com.tencent.mobileqqi:id/0', className="android.widget.EditText")
        if not_detection_robot.exists:
            if self.playCode(not_detection_robot):
                return False

        z.sleep(5)
        z.heartbeat()
        loginStatusList = z.qq_getLoginStatus(d)
        if loginStatusList is None:
            if d(resourceId='com.tencent.mobileqqi:id/0').exists and d(description='建讨论组').exists:
                loginStatusList = {'success': True}
            elif d(textContains="请在小米神隐模式中将TIM设置为“无限制”。").exists:
                z.toast(u"我是小米神隐")
                d(text='我知道了').click()
            else:
                loginStatusList = {'success': False}

        loginStatus = loginStatusList['success']
        if loginStatus:
            z.toast("QQ登陆成功,模块结束运行")
            return True
        else:
            if d(text='去安全中心').exists:
                self.repo.BackupInfo(args["repo_cate_id"], 'frozen', QQNumber, '', '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

            else:
                self.repo.BackupInfo(args["repo_cate_id"], 'normal', QQNumber, '', '')

            z.toast(u"QQ登陆失败,模块重新运行。")
            return False

        # if d(text='马上绑定').exists:
        #     self.BindAddressBook(z, d, args)

    def qiehuan(self , d, z, args):
        time_limit = int(args['time_limit'])
        serial = d.server.adb.device_serial()
        self.slot = Slot(serial, self.type)
        slotObj = self.slot.getAvailableSlot(time_limit)  # 没有空卡槽,取2小时没用过的卡槽
        slotnum = None
        if not slotObj is None:
            slotnum = slotObj['id']

        while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
            d.server.adb.cmd("shell",
                              "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\"").communicate()
            z.heartbeat()
            z.sleep(30)
            slotObj = self.slot.getAvailableSlot(time_limit)
            if not slotObj is None:
                slotnum = slotObj['id']
                break

        z.heartbeat()
        d.server.adb.cmd("shell", "pm clear com.tencent.mobileqqi").communicate()  # 清除缓存

        # d.server.adb.cmd("shell", "settings put global airplane_mode_on 1").communicate()  # 开飞行模式
        # d.server.adb.cmd("shell",
        #                   "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true").communicate()
        # d.server.adb.cmd("shell", "settings put global airplane_mode_on 0").communicate()  # 关飞行模式
        # d.server.adb.cmd("shell",
        #                   "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false").communicate()

        z.heartbeat()
        while True:
            ping = d.server.adb.cmd("shell", "ping -c 3 baidu.com").communicate()
            print(ping)
            if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                break
            z.sleep(2)

        obj = self.slot.getSlotInfo(slotnum)
        remark = obj['remark']
        remarkArr = remark.split("_")
        cateId = ""
        if len(remarkArr) == 3:
            slotInfo = d.server.adb.device_serial() + '_' + self.type + '_' + slotnum
            cateId = remarkArr[2]
            numbers = self.repo.Getserial(cateId, slotInfo)
            if len(numbers) != 0:
                featureCodeInfo = numbers[0]['imei']
                z.set_serial("com.tencent.mobileqqi", featureCodeInfo)

        self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽
        z.sleep(2)

        d.server.adb.cmd("shell",
                          "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" + slotnum + "号\"").communicate()
        z.sleep(2)
        d.server.adb.cmd("shell",
                          "am start -n com.tencent.mobileqqi/com.tencent.mobileqq.activity.SplashActivity").communicate()  # 拉起来
        z.sleep(5)
        while d(textContains='正在更新数据').exists:
            z.sleep(2)
        z.sleep(15)

        z.heartbeat()
        loginStatusList = z.qq_getLoginStatus(d)
        if loginStatusList is None:
            if d(resourceId='com.tencent.mobileqqi:id/0').exists and d(description='建讨论组').exists:
                loginStatusList = {'success': True}
            elif d(textContains="请在小米神隐模式中将TIM设置为“无限制”。").exists:
                z.toast(u"我是小米神隐")
                d(text='我知道了').click()
                loginStatusList = {'success': True}
            else:
                z.toast("登陆新场景,现无法判断登陆状态")
                loginStatusList = {'success': False}

        loginStatus = loginStatusList['success']
        if loginStatus:
            z.toast(u"卡槽QQ状态正常,继续执行")
            return True
        else:
            QQnumber = remarkArr[1]
            if d(text='去安全中心').exists:
                self.repo.BackupInfo(cateId, 'frozen', QQnumber, '', '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

            else:
                self.repo.BackupInfo(cateId, 'normal', QQnumber, '', '')

            self.slot.clear(slotnum)  # 清空改卡槽,并补登
            z.toast(u"卡槽QQ状态异常,补登陆卡槽")
            return False

    def action(self, d, z, args):
        while True:
            z.toast("正在ping网络是否通畅")
            i = 0
            # while i < 200:
            #     i += 1
            #     ping = d.server.adb.cmd("shell", "ping -c 3 baidu.com").communicate()
            #     print(ping)
            #     if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
            #         z.toast(u"网络通畅。开始执行:国际版QQ登录  有卡槽")
            #         break
            #     z.sleep(2)
            # if i > 200 :
            #     z.toast(u"网络不通,请检查网络状态")
            #     if (args["time_delay"]):
            #         z.sleep(int(args["time_delay"]))
            #     return
            #
            # z.heartbeat()
            # z.generate_serial("com.tencent.mobileqqi") # 随机生成手机特征码
            cate_id = args["repo_cate_id"]

            time_limit1 = args['time_limit1']
            numbers = self.repo.GetAccount(cate_id, time_limit1, 1)
            if len(numbers) == 0:
                d.server.adb.cmd("shell", "am broadcast -a com.zunyun.zime.toast --es msg \"QQ帐号库%s号仓库无%s分钟未用,开始切换卡槽\"" % (cate_id, time_limit1)).communicate()

            serial = d.server.adb.device_serial()
            self.slot = Slot(serial, self.type)
            slotnum = self.slot.getEmpty()  # 取空卡槽
            if slotnum == 0 or len(numbers) == 0:    #没有空卡槽的话
               if self.qiehuan(d, z, args):
                   break

            else:  # 有空卡槽的情况
                # d.server.adb.cmd("shell", "settings put global airplane_mode_on 1").communicate()
                # d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true").communicate()
                # z.sleep(6)
                # d.server.adb.cmd("shell", "settings put global airplane_mode_on 0").communicate()
                # d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false").communicate()
                z.heartbeat()
                while True:
                    ping = d.server.adb.cmd("shell", "ping -c 3 baidu.com").communicate()
                    print(ping)
                    if 'icmp_seq'and 'bytes from'and'time' in ping[0]:
                        break
                    z.sleep(2)

                z.heartbeat()
                if self.login(d, args, z, numbers):
                    z.heartbeat()
                    featureCodeInfo = z.get_serial("com.tencent.mobileqq")
                    self.slot.backup(slotnum, str(slotnum) + '_' + numbers[0]['number'] + '_' + cate_id)  # 设备信息,卡槽号,QQ号
                    self.repo.BackupInfo(cate_id, 'using', numbers[0]['number'], featureCodeInfo, '%s_%s_%s' % (d.server.adb.device_serial(), self.type, slotnum))  # 仓库号,使用中,QQ号,设备号_卡槽号
                    break

        if args["time_delay"]:
            z.sleep(int(args["time_delay"]))
예제 #3
0
class TIMLoginSlot:

    def __init__(self):
        self.repo = Repo()
        self.type = 'tim'

    def GetUnique(self):
        nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S");  # 生成当前时间
        randomNum = random.randint(0, 1000);  # 生成的随机整数n,其中0<=n<=100
        if randomNum <= 10:
            randomNum = str(00) + str(randomNum);
        uniqueNum = str(nowTime) + str(randomNum);
        return uniqueNum

    def WebViewBlankPages(self, d):
        z.toast( "判断是否是空白页" )
        Str = d.info  # 获取屏幕大小等信息
        height = float( Str["displayHeight"] )
        width = float( Str["displayWidth"] )

        W_H = width / height
        screenScale = round( W_H, 2 )

        base_dir = os.path.abspath( os.path.join( os.path.dirname( __file__ ), os.path.pardir, "tmp" ) )
        if not os.path.isdir( base_dir ):
            os.mkdir( base_dir )
        sourcePng = os.path.join( base_dir, "%s_s.png" % (self.GetUnique( )) )

        if screenScale == 0.56:
            left = 60  # 验证码的位置信息
            top = 655
            right = 290
            bottom = 680
        if screenScale == 0.61:
            left = 60  # 验证码的位置信息
            top = 490
            right = 210
            bottom = 510

        left = width * 7 / 135  # 验证码的位置信息
        top = height * 245 / 444
        right = width * 51 / 54
        bottom = height * 275 / 444

        d.screenshot( sourcePng )  # 截取整个输入验证码时的屏幕

        img = Image.open( sourcePng )
        box = (left, top, right, bottom)  # left top right bottom
        region = img.crop( box )  # 截取验证码的图片
        # show(region)    #展示资料卡上的信息
        image = region.convert( 'RGBA' )
        # 生成缩略图,减少计算量,减小cpu压力
        image.thumbnail( (200, 200) )
        max_score = None
        dominant_color = None
        for count, (r, g, b, a) in image.getcolors( image.size[0] * image.size[1] ):
            # 跳过纯黑色
            if a == 0:
                continue
            saturation = colorsys.rgb_to_hsv( r / 255.0, g / 255.0, b / 255.0 )[1]
            y = min( abs( r * 2104 + g * 4130 + b * 802 + 4096 + 131072 ) >> 13, 235 )
            y = (y - 16.0) / (235 - 16)
            # 忽略高亮色
            if y > 0.9:
                continue

            score = (saturation + 0.1) * count
            if score > max_score:
                max_score = score
                dominant_color = (r, g, b)  # 红绿蓝
        return dominant_color

    def WebViewPlayCode(self, d, z):
        z.toast( "开始截图打码" )

        Str = d.info  # 获取屏幕大小等信息
        height = float( Str["displayHeight"] )
        width = float( Str["displayWidth"] )
        W_H = width / height
        screenScale = round( W_H, 2 )

        base_dir = os.path.abspath( os.path.join( os.path.dirname( __file__ ), os.path.pardir, "tmp" ) )
        if not os.path.isdir( base_dir ):
            os.mkdir( base_dir )
        sourcePng = os.path.join( base_dir, "%s_s.png" % (self.GetUnique( )) )
        icode = imageCode( )
        im_id = ""
        for i in range( 0, 1 ):  # 打码循环
            if i > 0:
                icode.reportError( im_id )

            d.screenshot( sourcePng )  # 截取整个输入验证码时的屏幕
            if screenScale == 0.61:
                p = {"x1": 30 / width, "y1": 283 / height, "x2": 271 / width, "y2": 379 / height}
            if screenScale == 0.56:
                p = {"x1": 40 / width, "y1": 375 / height, "x2": 362 / width, "y2": 505 / height}
            cropedImg = z.img_crop( sourcePng, p )
            im = open( cropedImg, 'rb' )
            codeResult = icode.getCode( im, icode.CODE_TYPE_4_NUMBER_CHAR, 60 )
            code = codeResult["Result"]
            im_id = codeResult["Id"]
            os.remove( sourcePng )
            z.heartbeat( )
            z.sleep( 5 )
            d.click( width * 300 / 540, height * 330 / 888 )
            self.input( z, height, code )
            z.sleep( 2 )
            d.click( width * 270 / 540, height * 525 / 888 )
            while d( className='android.widget.ProgressBar', index=0 ).exists:  # 网速不给力时,点击完成后仍然在加载时的状态
                z.sleep( 2 )
            z.sleep( 8 )
            z.toast( "机器人打码--" )
            if not d( textContains='验证码' ).exists:
                z.toast( "机器人打码跳出--" )
                break

    def LoginPlayCode(self, d, z):
        self.scode = smsCode( d.server.adb.device_serial( ) )
        base_dir = os.path.abspath( os.path.join( os.path.dirname( __file__ ), os.path.pardir, "tmp" ) )
        if not os.path.isdir( base_dir ):
            os.mkdir( base_dir )
        sourcePng = os.path.join( base_dir, "%s_s.png" % (self.GetUnique( )) )
        codePng = os.path.join( base_dir, "%s_c.png" % (self.GetUnique( )) )
        detection_robot = d( index='3', className="android.widget.EditText" )
        not_detection_robot = d( resourceId='com.tencent.tim:id/name', index='2',
                                 className="android.widget.EditText" )
        if detection_robot.exists or not_detection_robot.exists:  # 需要验证码的情况
            icode = imageCode( )
            im_id = ""
            for i in range( 0, 4 ):  # 打码循环
                # if i > 0:
                #     icode.reportError( im_id )
                obj = d( resourceId='com.tencent.tim:id/name',
                         className='android.widget.ImageView' )  # 当弹出选择QQ框的时候,定位不到验证码图片
                if not obj.exists:
                    obj = d( index='2', className='android.widget.Image' )
                obj = obj.info
                obj = obj['bounds']  # 验证码处的信息
                left = obj["left"]  # 验证码的位置信息
                top = obj['top']
                right = obj['right']
                bottom = obj['bottom']

                d.screenshot( sourcePng )  # 截取整个输入验证码时的屏幕

                img = Image.open( sourcePng )
                box = (left, top, right, bottom)  # left top right bottom
                region = img.crop( box )  # 截取验证码的图片

                img = Image.new( 'RGBA', (right - left, bottom - top) )
                img.paste( region, (0, 0) )

                img.save( codePng )
                with open( codePng, 'rb' ) as f:
                    # file = f.read()
                    file = "data:image/jpeg;base64," + base64.b64encode( f.read( ) )
                    da = {"IMAGES": file}
                    path = "/ocr.index"
                    headers = {"Content-Type": "application/x-www-form-urlencoded",
                               "Connection": "Keep-Alive"}
                    conn = httplib.HTTPConnection( "162626i1w0.51mypc.cn", 10082, timeout=30 )
                    params = urllib.urlencode( da )
                    conn.request( method="POST", url=path, body=params, headers=headers )
                    response = conn.getresponse( )
                    if response.status == 200:
                        code = response.read( )
                    else:
                        continue
                os.remove( sourcePng )
                os.remove( codePng )
                z.heartbeat( )
                z.sleep( 5 )
                if not_detection_robot.exists:
                    d( resourceId='com.tencent.tim:id/name', index='2',
                       className="android.widget.EditText" ).set_text( code )
                else:
                    detection_robot.set_text( code )
                z.sleep( 3 )
                if d( descriptionContains='验证', className='android.view.View' ).exists:
                    d( descriptionContains='验证', className='android.view.View' ).click( )
                else:
                    d( text='完成', resourceId='com.tencent.tim:id/ivTitleBtnRightText' ).click( )
                z.sleep( 5 )
                z.heartbeat( )
                while d( className='android.widget.ProgressBar', index=0 ).exists:  # 网速不给力时,点击完成后仍然在加载时的状态
                    z.sleep( 2 )
                z.heartbeat( )
                if detection_robot.exists or not_detection_robot.exists:
                    continue
                else:
                    break
            z.sleep( 5 )
            if d( textContains='验证码' ).exists:
                return "no"
            else:
                return "yes"
        else:
            return "no"

    def login(self,d,args,z):
        z.heartbeat()
        Str = d.info  # 获取屏幕大小等信息
        height = float( Str["displayHeight"] )
        width = float( Str["displayWidth"] )

        cate_id = args["repo_cate_id"]
        time_limit1 = args['time_limit1']
        numbers = self.repo.GetAccount( cate_id, time_limit1, 1 )
        while len( numbers ) == 0:
            z.heartbeat( )
            d.server.adb.cmd( "shell", "am broadcast -a com.zunyun.zime.toast --es msg \"QQ帐号库%s号仓库无%s分钟未用,开始切换卡槽\"" % (
            cate_id, time_limit1) ).communicate( )
            z.sleep( 2 )
            return 0

        QQNumber = numbers[0]['number']  # 即将登陆的QQ号
        QQPassword = numbers[0]['password']
        z.sleep( 1 )
        z.heartbeat( )
        d.server.adb.cmd("shell", "pm clear com.tencent.tim").communicate( )  # 清除缓存
        # d.server.adb.cmd("shell",
        #                   "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity" ).communicate( )  # 拉起来
        z.server.adb.run_cmd( "shell", "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity" )
        z.sleep(10)
        while d( textContains='正在更新数据' ).exists:
            z.sleep( 2 )
        z.sleep(10)
        z.heartbeat()
        z.server.adb.run_cmd( "shell", "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity" )
        z.sleep( 5 )
        z.heartbeat( )
        if d(className='android.widget.ImageView',resourceId='com.tencent.tim:id/title',index=1).exists:
            for i in range(0,2):
                d.swipe( width - 20, height / 2, 0, height / 2, 5 )
                z.sleep(1.5)
            if d(text='立即体验').exists:
                d(text='立即体验').click()
        z.sleep(2)
        if d(text='登 录').exists:
            d(text='登 录').click()
        else:
           d( text='QQ号登录' ).click( )
        z.sleep( 1 )
        # d(className='android.widget.EditText', index=0).set_text(QQNumber)  # 1918697054----xiake1234.  QQNumber
        d(className='android.widget.EditText', index=0).click()  # 1918697054----xiake1234.  QQNumber
        self.input( z, height, QQNumber )

        z.sleep( 1 )
        # d(resourceId='com.tencent.mobileqq:id/password').set_text(QQPassword)  # Bn2kJq5l     QQPassword
        d(resourceId='com.tencent.tim:id/password').click()  # Bn2kJq5l     QQPassword
        self.input( z, height, QQPassword )
        z.heartbeat()
        logger = util.logger
        print('QQ号:%s,QQ密码:%s' % (QQNumber, QQPassword))
        d.dump(compressed=False )
        d( text='登 录', resourceId='com.tencent.tim:id/login' ).click( )
        z.sleep(1)
        while d(text='登录中').exists:
            z.sleep(2)

        z.sleep(int(args['time_delay1']))
        z.heartbeat()

        detection_robot = d( index='3', className="android.widget.EditText" )
        not_detection_robot = d( resourceId='com.tencent.tim:id/name', index='2',
                                 className="android.widget.EditText" )
        playCodeResult = ''
        if detection_robot.exists or not_detection_robot.exists:
            playCodeResult = self.LoginPlayCode( d, z )  # 打验证码
        else:
            if self.WebViewBlankPages( d )[2] > 200:
                z.toast( "不是空白页" )
                self.WebViewPlayCode( d, z )
            else:
                z.toast( "是空白页" )
                return "nothing"


        if playCodeResult == "no":
            return "nothing"

        z.sleep(10)
        z.heartbeat()
        if d( text='马上绑定' ).exists:
            return QQNumber

        if d(textContains="请在小米神隐模式中将TIM设置为“无限制”。").exists:
            z.toast("我是小米神隐")
            return QQNumber

        if d( text='匹配手机通讯录' ).exists:  # 登陆上后弹出t通讯录的情况
            d( text='匹配手机通讯录' ).click()
            z.sleep(1.5)
            if d(text='取消').exists:
                d(text='取消').child()
            return QQNumber

        if d(text='消息').exists and d(description='快捷入口').exists:
            z.toast("卡槽QQ状态正常,继续执行")
            return QQNumber

        if d( text='去安全中心' ).exists:
            self.repo.BackupInfo( cate_id, 'frozen', QQNumber, '', '' )  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
            z.toast( "登陆失败,重新登陆" )
            return "nothing"
        elif d(resourceId="com.tencent.tim:id/login",description="登录").exists:
            failCount = int(args["failCount"])
            for r in range(failCount):
                result = self.againLogin(d,z)
                if result is True:
                    return QQNumber
                elif result is False:
                    self.repo.BackupInfo( cate_id, 'frozen', QQNumber, '', '' )  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                    return "nothing"
                elif result is None:
                    return "nothing"
        else:
            self.repo.BackupInfo( cate_id, 'normal', QQNumber, '', '' )  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
            z.toast( "登陆失败,重新登陆" )
            return "nothing"

    def qiehuan(self, d, z, args):
        Str = d.info  # 获取屏幕大小等信息
        height = float( Str["displayHeight"] )
        width = float( Str["displayWidth"] )
        time_limit = int(args['time_limit'])
        cate_id = args["repo_cate_id"]
        serial = d.server.adb.device_serial( )
        self.slot = Slot( serial, self.type )
        slotObj = self.slot.getAvailableSlot(time_limit)  # 没有空卡槽,取2小时没用过的卡槽
        while slotObj is None:  # 2小时没有用过的卡槽也为空的情况
            d.server.adb.cmd("shell",
                             "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\"").communicate()
            z.heartbeat()
            z.sleep(10)
            slotObj = self.slot.getAvailableSlot( time_limit )  # 没有空卡槽,取2小时没用过的卡槽

        if not slotObj is None:
            slotnum = slotObj['id']
        z.heartbeat()
        d.server.adb.cmd("shell", "pm clear com.tencent.tim").communicate()  # 清除缓存

        # d.server.adb.cmd("shell", "settings put global airplane_mode_on 1").communicate()
        # d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true").communicate()
        # z.sleep(6)
        # z.heartbeat()
        # d.server.adb.cmd("shell", "settings put global airplane_mode_on 0").communicate()
        # d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false").communicate()
        z.heartbeat()
        z.toast( "正在ping网络是否通畅" )
        while True:
            ping = d.server.adb.cmd("shell", "ping -c 3 baidu.com").communicate()
            print(ping)
            if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                break
            z.sleep(2)

        obj = self.slot.getSlotInfo( slotnum )
        remark = obj['remark']
        remarkArr = remark.split( "_" )
        if len( remarkArr ) == 3:
            slotInfo = d.server.adb.device_serial( ) + '_' + self.type + '_' + slotnum
            cateId = remarkArr[2]
            numbers = self.repo.Getserial( cateId, slotInfo )
            if len( numbers ) != 0:
                featureCodeInfo = numbers[0]['imei']
                z.set_serial( "com.tencent.tim", featureCodeInfo )

        self.slot.restore( slotnum )  # 有time_limit分钟没用过的卡槽情况,切换卡槽

        d.server.adb.cmd("shell", "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" + str(slotnum) + "号\"").communicate()
        z.sleep(2)
        # d.server.adb.cmd("shell", "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity").communicate()  # 拉起来
        z.server.adb.run_cmd( "shell", "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity" )

        z.sleep( 5 )
        while d( textContains='正在更新数据' ).exists:
            z.sleep( 2 )

        z.sleep( 3 )
        z.server.adb.run_cmd( "shell", "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity" )
        z.sleep(3)
        z.heartbeat()
        if d(className='android.widget.ImageView',resourceId='com.tencent.tim:id/title',index=1).exists:
            for i in range(0,2):
                d.swipe( width - 20, height / 2, 0, height / 2, 5 )
                z.sleep(1.5)
            if d(text='立即体验').exists:
                d(text='立即体验').click()
        z.sleep(3)

        if d( textContains="请在小米神隐模式中将TIM设置为“无限制”。" ).exists:
            z.toast( "我是小米神隐" )
            d( text='我知道了' ).click( )
            d( text='我知道了' ).click( )
        elif d( text='消息' ).exists or d( text='马上绑定' ).exists or d( text='匹配手机通讯录' ).exists:
            if d( text='匹配手机通讯录' ).exists:  # 登陆上后弹出t通讯录的情况
                d( text='匹配手机通讯录' ).click( )
                z.sleep( 1.5 )
                if d( text='取消' ).exists:
                    d( text='取消' ).child( )
            z.toast( "卡槽QQ切换成功,继续执行" )
        else:
            obj = self.slot.getSlotInfo( slotnum )
            remark = obj['remark']
            remarkArr = remark.split( "_" )
            QQnumber = remarkArr[1]
            if d( text='去安全中心' ).exists:
                self.repo.BackupInfo( cate_id, 'frozen', QQnumber, '', '' )  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

            else:
                self.repo.BackupInfo( cate_id, 'normal', QQnumber, '', '' )
            self.slot.clear( slotnum )  # 清空改卡槽,并补登
            z.toast( "卡槽QQ状态异常,补登陆卡槽" )
            self.action( d, z, args )

    def againLogin(self, d , z):
        if d(resourceId="com.tencent.tim:id/login",description="登录").exists:
            d( resourceId="com.tencent.tim:id/login", description="登录" ).click()
            z.sleep( 1 )
            while d( text='登录中' ).exists:
                z.sleep( 2 )

            z.sleep( int( args['time_delay1'] ) )
            z.heartbeat( )

            detection_robot = d( index='3', className="android.widget.EditText" )
            not_detection_robot = d( resourceId='com.tencent.tim:id/name', index='2',
                                     className="android.widget.EditText" )
            playCodeResult = ''
            if detection_robot.exists or not_detection_robot.exists:
                playCodeResult = self.LoginPlayCode( d, z )  # 打验证码
            else:
                if self.WebViewBlankPages( d )[2] > 200:
                    z.toast( "不是空白页" )
                    self.WebViewPlayCode( d, z )
                else:
                    z.toast( "是空白页" )
                    return "nothing"

            if playCodeResult == "no":
                return "nothing"

            z.sleep( 10 )
            z.heartbeat( )
            if d( text='马上绑定' ).exists:
                return True

            if d( textContains="请在小米神隐模式中将TIM设置为“无限制”。" ).exists:
                z.toast( "我是小米神隐" )
                return True

            if d( text='匹配手机通讯录' ).exists:  # 登陆上后弹出t通讯录的情况
                d( text='匹配手机通讯录' ).click( )
                z.sleep( 1.5 )
                if d( text='取消' ).exists:
                    d( text='取消' ).child( )
                return True

            if d( text='消息' ).exists and d( description='快捷入口' ).exists:
                z.toast( "卡槽QQ状态正常,继续执行" )
                return True

            if d( text='去安全中心' ).exists:
                # self.repo.BackupInfo( cate_id, 'frozen', QQNumber, '', '' )  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                z.toast( "登陆失败,重新登陆" )
                return False
            if d( resourceId="com.tencent.tim:id/login", description="登录" ).exists:
                return "nothing"
            else:
                # self.repo.BackupInfo( cate_id, 'normal', QQNumber, '', '' )  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                z.toast( "登陆失败,重新登陆" )
                return

    def input(self, z, height, text):
        if height>888:
            z.input(text)
        else:
            z.cmd( "shell", "am broadcast -a ZY_INPUT_TEXT --es text \\\"%s\\\"" % text )

    def action(self,d,z,args):
        Str = d.info  # 获取屏幕大小等信息
        height = float( Str["displayHeight"] )
        width = float( Str["displayWidth"] )

        z.generate_serial("com.tencent.tim")  # 随机生成手机特征码
        z.toast("随机生成手机特征码")


        time_limit = int(args['time_limit'])
        cate_id = args["repo_cate_id"]
        serial = d.server.adb.device_serial()
        self.slot = Slot(serial, self.type)
        slotnum = self.slot.getEmpty()  # 取空卡槽
        if slotnum == 0:  # 没有空卡槽的话
            slotObj = self.slot.getAvailableSlot(time_limit)  # 取空卡槽,取2小时没用过的卡槽
            if not slotObj is None:
                slotnum = slotObj['id']
            print(slotnum)
            while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
                d.server.adb.cmd( "shell",
                                  "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\"" ).communicate( )
                z.heartbeat()
                z.sleep(10)
                slotObj = self.slot.getAvailableSlot(time_limit)
                if not slotObj is None:
                    slotnum = slotObj['id']
            z.heartbeat()
            d.server.adb.cmd( "shell", "pm clear com.tencent.tim" ).communicate( )  # 清除缓存
            # d.server.adb.cmd( "shell", "am force-stop com.tencent.tim" ).communicate( )  # 强制停止


            # d.server.adb.cmd("shell", "settings put global airplane_mode_on 1").communicate() #开数据流量
            # d.server.adb.cmd("shell","am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true").communicate()#开飞行模式
            # z.sleep( 6 )
            # z.heartbeat( )
            # d.server.adb.cmd("shell", "settings put global airplane_mode_on 0").communicate() # 关数据流量
            # d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false").communicate()#开飞行模式

            # z.heartbeat( )
            # z.toast( "正在ping网络是否通畅" )
            # while True:
            #     ping = d.server.adb.cmd( "shell", "ping -c 3 baidu.com" ).communicate( )
            #     print( ping )
            #     if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
            #         break
            #     z.sleep( 2 )
            obj = self.slot.getSlotInfo( slotnum )
            remark = obj['remark']
            remarkArr = remark.split( "_" )
            if len( remarkArr ) == 3:
                slotInfo = d.server.adb.device_serial() + '_' + self.type + '_' + slotnum
                cateId = remarkArr[2]
                numbers = self.repo.Getserial( cateId, slotInfo)
                if len(numbers) != 0:
                    featureCodeInfo = numbers[0]['imei']
                    z.set_serial( "com.tencent.tim", featureCodeInfo )

            self.slot.restore( slotnum )  # 有time_limit分钟没用过的卡槽情况,切换卡槽

            d.server.adb.cmd( "shell",
                              "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" + slotnum + "号\"" ).communicate( )
            z.sleep( 2 )
            # d.server.adb.cmd( "shell",
            #                   "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity" ).communicate( )  # 拉起来
            z.server.adb.run_cmd( "shell", "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity" )

            z.sleep(5)
            while d( textContains='正在更新数据' ).exists:
                z.sleep( 2 )
            z.sleep( 3 )
            z.server.adb.run_cmd( "shell", "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity" )
            z.sleep( 3 )

            if d( className='android.widget.ImageView', resourceId='com.tencent.tim:id/title', index=1 ).exists:
                for i in range( 0, 2 ):
                    d.swipe( width - 20, height / 2, 0, height / 2, 5 )
                    z.sleep( 1.5 )
                if d( text='立即体验' ).exists:
                    d( text='立即体验' ).click( )
            z.sleep( 2 )
            z.heartbeat()
            if d( textContains="请在小米神隐模式中将TIM设置为“无限制”。" ).exists:
                z.toast( "我是小米神隐" )
                d( text='我知道了' ).click( )
            elif d( text='消息' ).exists or d( text='马上绑定' ).exists or d( text='匹配手机通讯录' ).exists:
                if d( text='匹配手机通讯录' ).exists:  # 登陆上后弹出t通讯录的情况
                    d( text='匹配手机通讯录' ).click( )
                    z.sleep( 1.5 )
                    if d( text='取消' ).exists:
                        d( text='取消' ).child( )
                z.toast("卡槽QQ切换成功,继续执行")
            else:
                obj = self.slot.getSlotInfo( slotnum )
                remark = obj['remark']
                remarkArr = remark.split( "_" )
                QQnumber = remarkArr[1]
                if d(text='去安全中心').exists:
                    self.repo.BackupInfo(cate_id, 'frozen', QQnumber, '', '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

                else:
                    self.repo.BackupInfo(cate_id, 'normal', QQnumber, '', '')

                self.slot.clear( slotnum )  # 清空改卡槽,并补登
                z.toast("卡槽QQ状态异常,补登陆卡槽")
                self.action( d, z, args )

        else:  # 有空卡槽的情况
            d.server.adb.cmd( "shell", "pm clear com.tencent.tim" ).communicate( )  # 清除缓存

            # d.server.adb.cmd("shell", "settings put global airplane_mode_on 1").communicate()
            # d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true").communicate()
            # z.sleep(3)
            # d.server.adb.cmd("shell", "settings put global airplane_mode_on 0").communicate()
            # d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false").communicate()
            z.heartbeat( )
            # z.toast( "正在ping网络是否通畅" )
            # while True:
            #     ping = d.server.adb.cmd( "shell", "ping -c 3 baidu.com" ).communicate( )
            #     print( ping )
            #     if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
            #         break
            #     z.sleep( 2 )

            serialinfo = d.server.adb.device_serial( )
            # print('登陆时的serial%s'%serialinfo)
            z.heartbeat( )
            QQnumber = self.login( d, args, z )
            if QQnumber == 'nothing':
                self.slot.clear( slotnum )  # 清空改卡槽,并补登
                self.action( d, z, args )
            elif QQnumber == 0:
                z.toast( "仓库为空,无法登陆。开始切换卡槽" )
                self.qiehuan( d, z, args )
            elif QQnumber is None:
                return
            else:
                z.heartbeat()
                z.toast("登陆成功")
                featureCodeInfo = z.get_serial("com.tencent.tim")
                self.slot.backup( slotnum, str( slotnum ) + '_' + QQnumber + '_' + cate_id)  # 设备信息,卡槽号,QQ号
                self.repo.BackupInfo( cate_id, 'using', QQnumber, featureCodeInfo, '%s_%s_%s' % (
                    d.server.adb.device_serial( ), self.type, slotnum) )  # 仓库号,使用中,QQ号,设备号_卡槽号


        if (args["time_delay"]):
            time.sleep(int(args["time_delay"]))
예제 #4
0
class QQMailLogin:
    def __init__(self):
        self.repo = Repo()
        self.type = 'qqmail'

    def GetUnique(self):
        nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")  # 生成当前时间
        randomNum = random.randint(0, 1000)  # 生成的随机整数n,其中0<=n<=100
        if randomNum <= 10:
            randomNum = str(00) + str(randomNum)
        uniqueNum = str(nowTime) + str(randomNum)
        return uniqueNum

    def input(self, z, text):
        z.cmd("shell",
              "am broadcast -a ZY_INPUT_TEXT --es text \\\"%s\\\"" % text)

    def palyCode(self, d, z, picObj):
        self.scode = smsCode(d.server.adb.device_serial())
        base_dir = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir, "tmp"))
        if not os.path.isdir(base_dir):
            os.mkdir(base_dir)
        sourcePng = os.path.join(base_dir, "%s_s.png" % (self.GetUnique()))
        codePng = os.path.join(base_dir, "%s_c.png" % (self.GetUnique()))
        icode = imageCode()
        im_id = ""
        code = ""
        for i in range(0, 2):  # 打码循环
            if i > 0:
                icode.reportError(im_id)
            obj = picObj.info
            obj = obj['bounds']  # 验证码处的信息
            left = obj["left"]  # 验证码的位置信息
            top = obj['top']
            right = obj['right']
            bottom = obj['bottom']

            d.screenshot(sourcePng)  # 截取整个输入验证码时的屏幕

            img = Image.open(sourcePng)
            box = (left, top, right, bottom)  # left top right bottom
            region = img.crop(box)  # 截取验证码的图片

            img = Image.new('RGBA', (right - left, bottom - top))
            img.paste(region, (0, 0))

            img.save(codePng)
            im = open(codePng, 'rb')

            codeResult = icode.getCode(im, icode.CODE_TYPE_4_NUMBER_CHAR, 60)

            code = codeResult["Result"]
            im_id = codeResult["Id"]
            os.remove(sourcePng)
            os.remove(codePng)
            z.heartbeat()
            if code.isalpha() or code.isisdigitv() or code.isalnum():
                break
            else:
                continue

        return code

    def login(self, d, z, args, accounts):
        try:
            d.server.adb.cmd(
                "shell",
                "pm clear com.tencent.androidqqmail").communicate()  # 清除QQ邮箱缓存
            d.server.adb.cmd(
                "shell",
                "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail"
            ).communicate()  # 拉起QQ邮箱

            z.sleep(8)
            z.heartbeat()

            if args['mail_type'] == '163邮箱登录':
                if d(resourceId='com.tencent.androidqqmail:id/ee'
                     ).exists:  # 选择163邮箱点击进入登陆页面
                    d(resourceId='com.tencent.androidqqmail:id/ee').click()
                    z.sleep(1)

            if args['mail_type'] == 'QQ邮箱登录':
                if d(resourceId='com.tencent.androidqqmail:id/ea'
                     ).exists:  # 选择QQ邮箱点击进入登陆页面
                    d(resourceId='com.tencent.androidqqmail:id/ea').click()
                    z.sleep(1)

            if args['mail_type'] == '腾讯企业邮箱登录':
                if d(resourceId='com.tencent.androidqqmail:id/eb'
                     ).exists:  # 选择腾讯企业邮箱登录点击进入登陆页面
                    d(resourceId='com.tencent.androidqqmail:id/eb').click()
                    z.sleep(1)

            account = accounts[0]['number']
            password = accounts[0]['password']

            if d(text='帐号密码登录').exists:
                d(text='帐号密码登录').click()

            if d(resourceId='com.tencent.androidqqmail:id/bi'
                 ).exists:  # 输入邮箱帐号
                d(resourceId='com.tencent.androidqqmail:id/bi').click()
                # self.input(z,account)
                self.input(z, account)

            if d(resourceId='com.tencent.androidqqmail:id/bs'
                 ).exists:  # 输入邮箱密码
                d(resourceId='com.tencent.androidqqmail:id/bs').click()
                self.input(z, password)

            if d(resourceId='com.tencent.androidqqmail:id/a_'
                 ).exists:  # 点击登录按钮
                d(resourceId='com.tencent.androidqqmail:id/a_').click()

            z.sleep(25)
            while True:
                if d(text="验证中"):
                    time.sleep(3)
                else:
                    break
            if args['mail_type'] == 'QQ邮箱登录':
                if d(resourceId='com.tencent.androidqqmail:id/h'
                     ).exists:  # 判断是否要填写独立密码
                    self.input(z, "Abc" + account)
                    z.sleep(1)
                    if d(text='确定').exists:
                        d(text='确定').click()
                    z.sleep(5)

                while d(resourceId='com.tencent.androidqqmail:id/a16'
                        ).exists:  # 出现验证码
                    picObj = d(resourceId='com.tencent.androidqqmail:id/a19',
                               index=0)
                    code = self.palyCode(d, z, picObj)
                    if code == "":
                        return False
                    if d(resourceId='com.tencent.androidqqmail:id/a17').exists:
                        d(resourceId='com.tencent.androidqqmail:id/a17').click(
                        )
                    self.input(z, code)
                    if d(resourceId='com.tencent.androidqqmail:id/a_'
                         ).exists:  # 点击登陆
                        d(resourceId='com.tencent.androidqqmail:id/a_').click()
                    z.sleep(8)

                if d(resourceId='com.tencent.androidqqmail:id/h'
                     ).exists:  # 判断是否要填写独立密码
                    self.input(z, "Abc" + account)
                    z.sleep(1)
                    if d(text='确定').exists:
                        d(text='确定').click()

            if args['mail_type'] == '163邮箱登录':
                if d(resourceId='com.tencent.androidqqmail:id/a_'
                     ).exists:  # 点击登录按钮
                    d(resourceId='com.tencent.androidqqmail:id/a_').click()

                z.sleep(3)
                z.heartbeat()

                d.server.adb.cmd("shell",
                                 "am force-stop com.tencent.androidqqmail"
                                 ).wait()  # 强制停止163邮箱
                d.server.adb.cmd(
                    "shell",
                    "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail"
                ).communicate()  # 拉起163邮箱

            if args['mail_type'] == '腾讯企业邮箱登录':
                if d(resourceId='com.tencent.androidqqmail:id/a_'
                     ).exists:  # 点击登录按钮
                    d(resourceId='com.tencent.androidqqmail:id/a_').click()

                z.sleep(3)
                z.heartbeat()

                if d(text='收件箱​').exists:
                    z.toast(u"登录成功。退出模块")
                    d.server.adb.cmd(
                        "shell", "am force-stop com.tencent.androidqqmail"
                    ).wait()  # 强制停止
                    return True
                else:
                    return False
                # d.server.adb.cmd("shell", "am force-stop com.tencent.androidqqmail").wait()  # 强制停止163邮箱
                # d.server.adb.cmd("shell", "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail").communicate()  # 拉起163邮箱

            z.sleep(12)
            z.heartbeat()
            if d(textContains='你有多个应用同时收到').exists:
                d(text='确定').click()
                z.sleep(2)

            if d(text='收件箱​').exists:
                z.toast(u"登录成功。退出模块")
                d.server.adb.cmd(
                    "shell",
                    "am force-stop com.tencent.androidqqmail").wait()  # 强制停止
                return True
            else:
                return False
        except:
            logging.exception("exception")
            z.toast(u"程序出现异常,模块退出")
            d.server.adb.cmd(
                "shell",
                "am force-stop com.tencent.androidqqmail").wait()  # 强制停止
            return False

    def qiehuan(self, d, z, args):
        if args['mail_type'] == '163邮箱登录':
            self.type = '163mail'
        time_limit = int(args['slot_time_limit'])
        serial = d.server.adb.device_serial()
        self.slot = Slot(serial, self.type)
        slotObj = self.slot.getAvailableSlot(time_limit)  # 没有空卡槽,取2小时没用过的卡槽

        slotnum = None
        if not slotObj is None:
            slotnum = slotObj['id']

        while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\""
            ).communicate()
            z.heartbeat()
            z.sleep(30)
            slotObj = self.slot.getAvailableSlot(time_limit)
            if not slotObj is None:
                slotnum = slotObj['id']
                break

        z.heartbeat()
        d.server.adb.cmd(
            "shell",
            "pm clear com.tencent.androidqqmail").communicate()  # 清除缓存

        obj = self.slot.getSlotInfo(slotnum)
        remark = obj['remark']
        remarkArr = remark.split("_")
        cateId = args['repo_account_id']
        if len(remarkArr) == 3:
            slotInfo = d.server.adb.device_serial(
            ) + '_' + self.type + '_' + slotnum
            cateId = remarkArr[2]
            numbers = self.repo.Getserial(cateId, slotInfo)
            if len(numbers) != 0:
                featureCodeInfo = numbers[0]['imei']
                z.set_serial("com.tencent.androidqqmail", featureCodeInfo)

        self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽
        z.sleep(2)

        d.server.adb.cmd(
            "shell",
            "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" +
            slotnum + "号\"").communicate()
        z.sleep(2)
        d.server.adb.cmd(
            "shell",
            "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail"
        ).communicate()  # 拉起QQ邮箱
        z.sleep(5)
        while d(textContains='正在更新数据').exists:
            z.sleep(2)
        z.sleep(20)

        z.heartbeat()
        d.dump(compressed=False)
        if d(text='密码错误,请重新输入').exists or d(description='QQ邮箱').exists:
            QQnumber = remarkArr[1]
            self.repo.BackupInfo(cateId, 'normal', QQnumber, '',
                                 '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

            self.slot.clear(slotnum)  # 清空改卡槽,并补登
            z.toast("卡槽邮箱号状态异常,补登陆卡槽")
            return False

        else:
            z.toast("邮箱登陆状态正常,切换完毕。")
            return True

    def action(self, d, z, args):

        while True:
            # z.toast("正在ping网络是否通畅")
            # i = 0
            # while i < 200:
            #     i += 1
            #     ping = d.server.adb.cmd("shell", "ping -c 3 baidu.com").communicate()
            #     # print(ping)
            #     if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
            #         z.toast(u"网络通畅。开始执行:" + args['mail_type'] + u" 有卡槽")
            #         break
            #     z.sleep(2)
            # if i > 200:
            #     z.toast(u"网络不通,请检查网络状态")
            #     return

            z.heartbeat()
            z.generate_serial("com.tencent.androidqqmail")  # 随机生成手机特征码

            if args['mail_type'] == '163邮箱登录':
                self.type = '163mail'

            accounts = self.repo.GetAccount(args['repo_account_id'],
                                            int(args['account_time_limit']),
                                            1)  # 去仓库获取QQ邮箱帐号
            if len(accounts) == 0:
                z.toast(u"帐号库为空")

            serial = d.server.adb.device_serial()
            self.slot = Slot(serial, self.type)
            slotnum = self.slot.getEmpty()  # 取空卡槽
            if slotnum == 0 or len(
                    accounts) == 0:  # 没有空卡槽的话或者仓库没有可登陆的帐号,进行卡槽切换。
                if self.qiehuan(d, z, args):
                    break
                else:
                    continue
            else:  # 有空卡槽的情况

                QQnumber = accounts[0]['number']
                # print QQnumber
                if self.login(d, z, args, accounts):
                    z.heartbeat()
                    featureCodeInfo = z.get_serial("com.tencent.androidqqmail")
                    self.slot.backup(slotnum,
                                     str(slotnum) + '_' + QQnumber + '_' +
                                     args["repo_account_id"])  # 设备信息,卡槽号,QQ号
                    self.repo.BackupInfo(
                        args["repo_account_id"], 'using', QQnumber,
                        featureCodeInfo,
                        '%s_%s_%s' % (d.server.adb.device_serial(), self.type,
                                      slotnum))  # 仓库号,使用中,QQ号,设备号_卡槽号
                    break

                else:
                    self.slot.clear(slotnum)  # 清空改卡槽,并补登
                    if d(text='本次登录存在异常,如需帮助请前往安全中心').exists:
                        z.toast(u"登录失败。重新登录")
                        self.repo.BackupInfo(args["repo_account_id"], 'frozen',
                                             QQnumber, '',
                                             '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                    elif d(text='帐号或密码错误').exists:
                        z.toast(u"帐号或密码错误")
                        self.repo.BackupInfo(args["repo_account_id"], 'frozen',
                                             QQnumber, '',
                                             '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                    else:
                        self.repo.BackupInfo(args["repo_account_id"], 'normal',
                                             QQnumber, '',
                                             '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                    continue
예제 #5
0
class YiXinLogin:
    def __init__(self):
        self.repo = Repo()
        self.type = 'yixin'

    def GenPassword(self, numOfNum=4, numOfLetter=4):
        # 选中numOfNum个数字
        slcNum = [random.choice( string.digits ) for i in range( numOfNum )]
        # 选中numOfLetter个字母
        slcLetter = [random.choice( string.lowercase ) for i in range( numOfLetter )]
        slcChar = slcLetter + slcNum
        genPwd = ''.join( [i for i in slcChar] )
        return genPwd


    def login(self, d, z, args, password):
        z.toast("开始登录")
        d.server.adb.cmd("shell", "pm clear im.yixin" ).communicate( )  # 清除缓存
        d.server.adb.cmd("shell", "am start -n im.yixin/.activity.WelcomeActivity" ).communicate( )  # 拉起易信
        z.sleep(10)
        z.heartbeat()
        if d(text='很抱歉,“易信”已停止运行。').exists:
            d( text='确定' ).click( )
            return 'fail'

        d.server.adb.cmd( "shell", "am force-stop im.yixin" ).communicate( )  # 强制停止
        d.server.adb.cmd( "shell", "am start -n im.yixin/.activity.WelcomeActivity" ).communicate( )  # 拉起易信
        z.sleep(5)
        z.heartbeat()
        if d( text='很抱歉,“易信”已停止运行。' ).exists:
            d( text='确定' ).click( )
            return 'fail'

        if d( text='接受', resourceId='im.yixin:id/easy_dialog_positive_btn' ).exists:
            d( text='接受', resourceId='im.yixin:id/easy_dialog_positive_btn' ).click( )
            z.sleep( 2 )

        if d( text='登 录' ).exists:
            d( text='登 录' ).click()
            z.sleep( 2 )

        while True:
            z.heartbeat()
            z.toast(u"开始获取手机号码")
            self.scode = smsCode( d.server.adb.device_serial( ) )

            str = d.info  # 获取屏幕大小等信息
            height = str["displayHeight"]
            width = str["displayWidth"]

            if d( resourceId='im.yixin:id/register_phone_number_edittext' ).exists:
                d( resourceId='im.yixin:id/register_phone_number_edittext' ).click.bottomright( )


            number_cate_id = args['repo_number_id']
            # number_time_limit = int(args['number_time_limit'])  # 号码提取时间间隔
            exist_numbers = self.repo.GetNumber( number_cate_id, 0, 1, 'exist' )
            remain = 1 - len( exist_numbers )
            normal_numbers = self.repo.GetNumber( number_cate_id, 0, remain, 'normal' )
            numbers = exist_numbers + normal_numbers
            if len( numbers ) == 0:
                d.server.adb.cmd("shell",
                              "am broadcast -a com.zunyun.zime.toast --es msg \"电话号码%s号仓库为空\"" % number_cate_id).communicate()
                return None

            number = numbers[0]["number"]

            if d(resourceId='im.yixin:id/editUserid').exists:
                d(resourceId='im.yixin:id/editUserid').click()

            try:
                PhoneNumber = self.scode.GetPhoneNumber(self.scode.WECHAT_REGISTER, number)  # 获取接码平台手机号码
            except:
                PhoneNumber = None

            # PhoneNumber = self.scode.GetPhoneNumber(self.scode.WECHAT_REGISTER)  # 获取接码平台手机号码

            if PhoneNumber is None:
                z.toast(u'讯码查不无此号,重新获取')
                continue
            else:
                z.toast(u"成功获取手机号")
                break

        z.input(PhoneNumber)

        if d(text='找回密码').exists:
            d(text='找回密码').click()
            z.sleep(3)

        if not d(text='中国',resourceId='im.yixin:id/country_name').exists:
            d( resourceId='im.yixin:id/country_name' ).click()
            z.sleep(1)
            while True:
                if d( text='中国').exists:
                    d( text='中国' ).click()
                    break
                else:
                    d.swipe( width / 2, height * 6 / 7, width / 2, height / 7 )

        if d(text='下一步').exists:
            d(text='下一步').click()
            z.sleep(8)

        z.heartbeat()
        if d(text='注册',resourceId='im.yixin:id/easy_dialog_positive_btn').exists:
            return "fail"

        if d(text='输入收到的验证码').exists:
            d(text='输入收到的验证码').click()

        try:
            code = self.scode.GetVertifyCode( PhoneNumber, self.scode.WECHAT_REGISTER, 4)  # 获取接码验证码
            self.scode.defriendPhoneNumber( PhoneNumber, self.scode.WECHAT_REGISTER )
        except:
            self.scode.defriendPhoneNumber( PhoneNumber, self.scode.WECHAT_REGISTER )
            code = ''

        if code == '':
            z.toast( PhoneNumber + '手机号,获取不到验证码' )
            return "fail"

        z.input(code)
        if d(text='下一步').exists:
            d(text='下一步').click()
            z.sleep(8)

        if d(resourceId='im.yixin:id/password_edittext').exists:
            z.input(password)
            z.sleep(1)
            d(text='完成').click()
            z.sleep(15)
            z.heartbeat()

        if d(text='立即更新').exists and d(text='下次再说').exists:
            d(text='下次再说').click()

        if d(text='消息').exists and d(text='电话').exists and d(text='发现').exists and d(text='通讯录').exists:
            z.toast(u'登录成功')
            return PhoneNumber
        else:
            z.toast(u'登录失败,重新登录')
            return "fail"


    def qiehuan(self, d, z, args):
        z.toast("开始切换卡槽")
        slot_time_limit = int( args['slot_time_limit'] )  # 卡槽提取时间间隔
        slotObj = self.slot.getAvailableSlot(slot_time_limit)  # 取空卡槽,取N小时没用过的卡槽

        if not slotObj is None:
            slotnum = slotObj['id']

        while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
            d.server.adb.cmd("shell",
                              "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\"").communicate()
            z.heartbeat()
            z.sleep(10)
            slotObj = self.slot.getAvailableSlot(slot_time_limit)
            if not slotObj is None:
                slotnum = slotObj['id']

        z.heartbeat()
        print(slotnum)

        obj = self.slot.getSlotInfo( slotnum )
        remark = obj['remark']
        remarkArr = remark.split( "_" )
        if len( remarkArr ) == 3:
            slotInfo = d.server.adb.device_serial( ) + '_' + self.type + '_' + slotnum
            cateId = remarkArr[2]
            numbers = self.repo.Getserial( cateId, slotInfo )
            if len(numbers) > 0:
                featureCodeInfo = numbers[0]['imei']
                z.set_serial( "im.yixin", featureCodeInfo )

        d.server.adb.cmd( "shell", "pm clear im.yixin" ).communicate( )  # 清除缓存

        self.slot.restore( slotnum )  # 有time_limit分钟没用过的卡槽情况,切换卡槽

        d.server.adb.cmd( "shell",
                          "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" + slotnum + "号\"" ).communicate( )
        z.sleep( 2 )

        d.server.adb.cmd( "shell", "am start -n im.yixin/.activity.WelcomeActivity" ).communicate( )  # 拉起易信
        z.sleep(10)
        z.heartbeat()
        if d( text='很抱歉,“易信”已停止运行。' ).exists:
            d( text='确定' ).click()
            return 'fail'

        if d( text='立即更新' ).exists and d( text='下次再说' ).exists:
            d( text='下次再说' ).click( )

        if d( text='消息' ).exists and d( text='电话' ).exists and d( text='发现' ).exists and d( text='通讯录' ).exists:
            z.toast( u'切换成功' )
            return "success"
        else:
            z.toast( u'切换失败,重新补登' )
            self.repo.BackupInfo( cateId, 'exception', remarkArr[1], featureCodeInfo, '')  # 仓库号,使用中,QQ号,设备号_卡槽号
            return "fail"



    def action(self, d, z, args):
        z.toast( "正在ping网络是否通畅" )
        while True:
            ping = d.server.adb.cmd( "shell", "ping -c 3 baidu.com" ).communicate( )
            print(ping)
            if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                z.toast("开始执行:易信登录模块 有卡槽")
                break
            z.sleep( 2 )

        z.generate_serial( "im.yixin" )  # 随机生成手机特征码
        z.toast( "随机生成手机特征码" )

        saveCate = args['repo_account_id']
        password = self.GenPassword()

        serial = d.server.adb.device_serial()
        self.slot = Slot(serial, self.type)
        slotnum = self.slot.getEmpty()  # 取空卡槽

        if slotnum == 0:  # 没有空卡槽的话
            qiehuan_result = self.qiehuan(d, z, args)
            if qiehuan_result == "fail":
                self.action(d, z, args)
        else:
            login_result = self.login(d, z, args, password)
            if login_result == "fail":
                self.action(d, z, args)

            elif login_result is None:
                qiehuan_result = self.qiehuan( d, z, args )
                if qiehuan_result == "fail":
                    self.action( d, z, args )

            else:
                # 入库
                featureCodeInfo = z.get_serial("im.yixin")
                self.repo.RegisterAccount(login_result, password, "", saveCate, "using", featureCodeInfo, '%s_%s_%s' % (
                        d.server.adb.device_serial(), self.type, slotnum))
                # 入卡槽
                self.slot.backup(slotnum, str(slotnum) + '_' + login_result + '_' + saveCate)  # 设备信息,卡槽号,QQ号

        if (args['time_delay']):
            z.sleep(int(args['time_delay']))
예제 #6
0
class QQSafetyCenter:
    def __init__(self):
        self.repo = Repo()
        self.type = 'token'

    def GetUnique(self):
        nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
        # 生成当前时间
        randomNum = random.randint(0, 1000)
        # 生成的随机整数n,其中0<=n<=100
        if randomNum <= 10:
            randomNum = str(00) + str(randomNum)
        uniqueNum = str(nowTime) + str(randomNum)
        return uniqueNum

    def LoginPlayCode(self, d, z):
        self.scode = smsCode(d.server.adb.device_serial())
        base_dir = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir, "tmp"))
        if not os.path.isdir(base_dir):
            os.mkdir(base_dir)
        sourcePng = os.path.join(base_dir, "%s_s.png" % (self.GetUnique()))
        codePng = os.path.join(base_dir, "%s_c.png" % (self.GetUnique()))
        codeEditTextObj = d(resourceId='com.tencent.mobileqq:id/name',
                            index='2',
                            className="android.widget.EditText")
        if codeEditTextObj.exists:  # 需要验证码的情况
            icode = imageCode()
            im_id = ""
            for i in range(0, 4):  # 打码循环
                if i > 0:
                    icode.reportError(im_id)
                obj = d(resourceId='com.tencent.mobileqq:id/name',
                        className='android.widget.ImageView'
                        )  # 当弹出选择QQ框的时候,定位不到验证码图片
                obj = obj.info
                obj = obj['bounds']  # 验证码处的信息
                left = obj["left"]  # 验证码的位置信息
                top = obj['top']
                right = obj['right']
                bottom = obj['bottom']

                d.screenshot(sourcePng)  # 截取整个输入验证码时的屏幕

                img = Image.open(sourcePng)
                box = (left, top, right, bottom)  # left top right bottom
                region = img.crop(box)  # 截取验证码的图片

                img = Image.new('RGBA', (right - left, bottom - top))
                img.paste(region, (0, 0))

                img.save(codePng)
                im = open(codePng, 'rb')

                codeResult = icode.getCode(im, icode.CODE_TYPE_4_NUMBER_CHAR,
                                           60)

                code = codeResult["Result"]
                im_id = codeResult["Id"]
                os.remove(sourcePng)
                os.remove(codePng)

        return code

    def CaseOne(self, d, z, QQNumber,
                QQPassword):  # 登录情况一:手机上有qq登录或提示历史登陆过的帐号直接登陆

        if d(text='切换帐号').exists and d(text='添加帐号').exists:
            if d(resourceId='com.tencent.mobileqq:id/name', index=0).exists:
                obj = d(resourceId='com.tencent.mobileqq:id/name',
                        index=0,
                        className='android.widget.RelativeLayout').child(
                            className='android.widget.LinearLayout',
                            index=1).child(
                                resourceId='com.tencent.mobileqq:id/name',
                                index=0,
                                className='android.widget.LinearLayout').child(
                                    resourceId='com.tencent.mobileqq:id/name',
                                    index=0,
                                    className='android.widget.RelativeLayout')
                Str = obj.info["bounds"]  # 获取该控件大小等信息
                height = int(Str["bottom"]) - int(Str["top"])
                d.swipe(
                    int(Str["right"]) - 10,
                    int(Str["bottom"]) - height / 2,
                    int(Str["left"]) + 10,
                    int(Str["bottom"]) - height / 2, 5)
                z.sleep(1.5)
                if d(text='删除').exists:
                    d(text='删除').click()
                    z.sleep(1)
            d(text='添加帐号').click()

        d(resourceId='com.tencent.mobileqq:id/account').click()
        z.input(QQNumber)

        d(resourceId='com.tencent.mobileqq:id/password').click()
        z.input(QQPassword)

        if d(text='登 录').exists:
            d(text='登 录').click()
            z.sleep(5)

        if d(text='输入验证码').exists:
            code = self.LoginPlayCode(d, z)
            z.input(code)
            z.sleep(1)

            if d(text='完成').exists:
                d(text='完成').click()

    def CaseTwo(self, d, z, QQNumber, QQPassword):  #登录情况二:手机上没有登陆qq也没有登录过安全中心

        d(className='android.view.View', index=1).click()
        z.input(QQNumber)

        d(className='android.view.View', index=2).click()
        z.input(QQPassword)

        if d(description='登 录').exists:
            d(description='登 录').click()

    def Login(self, d, z, args):  #登录方法
        self.scode = smsCode(d.server.adb.device_serial())
        d.server.adb.cmd("shell",
                         "pm clear com.tencent.token").communicate()  # 清除缓存
        if d(text='QQ安全中心').exists:
            d(text='QQ安全中心').click()
            z.sleep(6)
        else:
            z.toast("请返回有QQ安全中心的主页面,再运行")
            d.server.adb.cmd(
                "shell", "pm clear com.tencent.token").communicate()  # 清除缓存
            return
        d.server.adb.cmd("shell",
                         "am start -n com.tencent.token/.ui.LogoActivity"
                         ).communicate()  # 拉起来
        z.sleep(6)

        if d(resourceId='com.tencent.token:id/account_bind_qqface').exists:
            d(resourceId='com.tencent.token:id/account_bind_qqface').click()
            z.sleep(1)

        if d(text='登录').exists:
            d(text='登录').click()
            z.sleep(0.5)

        if d(text='QQ登录').exists:
            d(text='QQ登录').click()
            z.sleep(1)

        cate_id = args["repo_cate_id"]
        time_limit = args['time_limit']
        numbers = self.repo.GetAccount(cate_id, time_limit, 1)
        print(numbers)
        while len(numbers) == 0:
            z.heartbeat()
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"QQ帐号库%s号仓库无%s分钟未用,开始切换卡槽\""
                % (cate_id, time_limit)).communicate()
            z.sleep(2)
            return "none"

        QQNumber = numbers[0]['number']  # 即将登陆的QQ号
        QQPassword = numbers[0]['password']
        # QQNumber = '3518608471'
        # QQPassword = '******'
        z.sleep(1)

        if d(text='切换帐号').exists:
            d(text='切换帐号').click()
            z.sleep(1)
            self.CaseOne(d, z, QQNumber, QQPassword)
            z.sleep(5)
        else:
            self.CaseTwo(d, z, QQNumber, QQPassword)
            z.sleep(5)

        if d(description='请向右拖动滑块完成拼图').exists:
            z.toast("遇到安全验证,重新开始")
            return "again"

        if d(text='身份验证').exists:
            d(text='下一步').click()

        if d(text='请填写您收到的短信验证码:').exists:
            info = numbers[0]['qqtoken']
            infoArray = info.split('----')
            number = infoArray[6]
            # number = "14773454349"
            try:
                PhoneNumber = self.scode.GetPhoneNumber(
                    self.scode.QQ_TOKEN_BIND, number)  # 获取接码平台手机号码
            except:
                logging.exception("exception")
                PhoneNumber = None

            if PhoneNumber is None:
                self.repo.BackupInfo(cate_id, 'frozen', QQNumber, '',
                                     '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                z.toast('查不无此号')
                return "again"

            try:
                code = self.scode.GetVertifyCode(
                    PhoneNumber, self.scode.QQ_TOKEN_BIND)  # 获取接码验证码
                self.scode.defriendPhoneNumber(PhoneNumber,
                                               self.scode.QQ_TOKEN_BIND)
            except:
                logging.exception("exception")
                code = ''

            if code == '':
                z.toast(PhoneNumber + '手机号,获取不到验证码')
                self.scode.defriendPhoneNumber(PhoneNumber,
                                               self.scode.QQ_TOKEN_BIND)
                return "again"

            z.input(code)
            if d(resourceId='com.tencent.token:id/sms_code'
                 ).exists:  #点击输入框输入验证码
                d(resourceId='com.tencent.token:id/sms_code').click()
                z.input(code)

            if d(text='下一步').exists:
                d(text='下一步').click()
                z.sleep(5)

            if d(text='开启安全之旅').exists:
                d(text='开启安全之旅').click()

            return QQNumber

            if d(textContains='绑定QQ失败').exists:
                return "again"

        elif d(text='登录失败').exists:
            return "again"

    def QieHuanSolt(self, d, z, args):  # 卡槽切换方法
        time_limit_slot = int(args['time_limit_slot'])
        slotObj = self.slot.getAvailableSlot(
            time_limit_slot)  # 取空卡槽,取2小时没用过的卡槽
        if not slotObj is None:
            slotnum = slotObj['id']
        print(slotnum)
        while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\""
            ).communicate()
            z.heartbeat()
            z.sleep(10)
            slotObj = self.slot.getAvailableSlot(time_limit_slot)
            if not slotObj is None:
                slotnum = slotObj['id']

        d.server.adb.cmd(
            "shell", "am broadcast -a com.zunyun.zime.toast --es msg \"正在切换到" +
            slotnum + "号卡槽...\"").communicate()
        self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽
        d.server.adb.cmd(
            "shell",
            "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" +
            slotnum + "号\"").communicate()

        if d(text='QQ安全中心').exists:
            d(text='QQ安全中心').click()
            z.sleep(6)
        d.server.adb.cmd("shell",
                         "pm clear com.tencent.token").communicate()  # 清除缓存
        d.server.adb.cmd(
            "shell", "am broadcast -a com.zunyun.zime.toast --es msg \"正在切换到" +
            slotnum + "号卡槽...\"").communicate()

        self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽

        d.server.adb.cmd(
            "shell",
            "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" +
            slotnum + "号\"").communicate()
        d.server.adb.cmd("shell",
                         "am start -n com.tencent.token/.ui.LogoActivity"
                         ).communicate()  # 拉起来
        z.sleep(10)

        if d(text='欢迎来到安全中心').exists:
            return "fail"

        return "success"

    def action(self, d, z, args):
        z.generate_serial("com.tencent.tim")  # 随机生成手机特征码
        z.toast("随机生成手机特征码")

        serial = d.server.adb.device_serial()
        cate_id = args["repo_cate_id"]
        self.slot = Slot(serial, self.type)
        slotnum = self.slot.getEmpty()  # 取空卡槽

        if slotnum == 0:
            QieHuanSolt_Result = self.QieHuanSolt(d, z, args)
            if QieHuanSolt_Result == "fail":
                obj = self.slot.getSlotInfo(slotnum)
                remark = obj['remark']
                remarkArr = remark.split("_")
                QQnumber = remarkArr[1]
                self.repo.BackupInfo(cate_id, 'frozen', QQnumber, '',
                                     '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                self.slot.clear(slotnum)  # 清空改卡槽,并补登
                z.toast("卡槽恢复失败,进行补登")
                self.action(d, z, args)

            else:
                z.toast("卡槽恢复成功,帐号正常")

        else:
            Login_Result = self.Login(d, z, args)
            if Login_Result == "again":
                self.action(d, z, args)

            elif Login_Result == "none":  # 有空卡槽,单仓库无帐号可登,继续继续切换卡槽
                QieHuanSolt_Result = self.QieHuanSolt(d, z, args)
                if QieHuanSolt_Result == "fail":
                    obj = self.slot.getSlotInfo(slotnum)
                    remark = obj['remark']
                    remarkArr = remark.split("_")
                    QQnumber = remarkArr[1]
                    self.repo.BackupInfo(cate_id, 'frozen', QQnumber, '',
                                         '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                    self.slot.clear(slotnum)  # 清空改卡槽,并补登
                    z.toast("卡槽恢复失败,进行补登")
                    self.action(d, z, args)

                else:
                    z.toast("卡槽恢复成功,帐号正常")

            else:
                QQnumber = Login_Result
                self.slot.backup(slotnum,
                                 str(slotnum) + '_' + QQnumber)  # 设备信息,卡槽号,QQ号
                self.repo.BackupInfo(cate_id, 'using', QQnumber, serial,
                                     '%s_%s_%s' %
                                     (d.server.adb.device_serial(), self.type,
                                      slotnum))  # 仓库号,使用中,QQ号,设备号_卡槽号
예제 #7
0
class YiXinAccountLogin:
    def __init__(self):
        self.repo = Repo()
        self.type = 'yixin'

    def login(self, d, z, args):
        z.toast("开始登录")
        d.server.adb.cmd("shell", "pm clear im.yixin").communicate()  # 清除缓存
        d.server.adb.cmd("shell",
                         "am start -n im.yixin/.activity.WelcomeActivity"
                         ).communicate()  # 拉起易信
        z.sleep(10)
        z.heartbeat()
        if d(text='很抱歉,“易信”已停止运行。').exists:
            d(text='确定').click()
            return 'fail'

        d.server.adb.cmd("shell",
                         "am force-stop im.yixin").communicate()  # 强制停止
        d.server.adb.cmd("shell",
                         "am start -n im.yixin/.activity.WelcomeActivity"
                         ).communicate()  # 拉起易信
        z.sleep(5)
        z.heartbeat()
        if d(text='很抱歉,“易信”已停止运行。').exists:
            d(text='确定').click()
            return 'fail'

        if d(text='接受',
             resourceId='im.yixin:id/easy_dialog_positive_btn').exists:
            d(text='接受',
              resourceId='im.yixin:id/easy_dialog_positive_btn').click()
            z.sleep(2)

        if d(text='登 录').exists:
            d(text='登 录').click()
            z.sleep(2)

        z.toast(u"开始获取手机号码")
        cate_id = args["repo_account_id"]
        account_time_limit = args['account_time_limit']
        numbers = self.repo.GetAccount(cate_id, account_time_limit, 1)
        if len(numbers) == 0:
            z.heartbeat()
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"QQ帐号库%s号仓库无%s分钟未用,开始切换卡槽\""
                % (cate_id, account_time_limit)).communicate()
            z.sleep(2)
            return None

        featureCodeInfo = numbers[0]['imei']
        if not featureCodeInfo is None:
            z.set_serial("im.yixin", featureCodeInfo)
        else:
            z.generate_serial("im.yixin")  # 随机生成手机特征码
            z.toast("随机生成手机特征码")

        PhoneNumber = numbers[0]['number']  # 即将登陆的QQ号
        Password = numbers[0]['password']

        if d(resourceId='im.yixin:id/editUserid').exists:
            d(resourceId='im.yixin:id/editUserid').click.bottomright()

        if d(resourceId='im.yixin:id/editUserid').exists:
            d(resourceId='im.yixin:id/editUserid').click()
            z.input(PhoneNumber)

        if d(resourceId='im.yixin:id/editPassword').exists:
            d(resourceId='im.yixin:id/editPassword').click.bottomright()

        if d(resourceId='im.yixin:id/editPassword').exists:
            d(resourceId='im.yixin:id/editPassword').click()
            z.input(Password)

        if d(text='完成').exists:
            d(text='完成').click()
            z.sleep(15)

        z.heartbeat()
        if d(text='立即更新').exists and d(text='下次再说').exists:
            d(text='下次再说').click()

        if d(text='消息').exists and d(text='电话').exists and d(
                text='发现').exists and d(text='通讯录').exists:
            z.toast(u'登录成功')
            return PhoneNumber
        else:
            z.toast(u'登录失败,重新登录')
            return "fail"

    def qiehuan(self, d, z, args):
        z.toast("开始切换卡槽")
        slot_time_limit = int(args['slot_time_limit'])  # 卡槽提取时间间隔
        slotObj = self.slot.getAvailableSlot(
            slot_time_limit)  # 取空卡槽,取N小时没用过的卡槽

        if not slotObj is None:
            slotnum = slotObj['id']

        while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\""
            ).communicate()
            z.heartbeat()
            z.sleep(10)
            slotObj = self.slot.getAvailableSlot(slot_time_limit)
            if not slotObj is None:
                slotnum = slotObj['id']

        z.heartbeat()
        print(slotnum)

        obj = self.slot.getSlotInfo(slotnum)
        remark = obj['remark']
        remarkArr = remark.split("_")
        if len(remarkArr) == 3:
            slotInfo = d.server.adb.device_serial(
            ) + '_' + self.type + '_' + slotnum
            cateId = remarkArr[2]
            numbers = self.repo.Getserial(cateId, slotInfo)
            if len(numbers) > 0:
                featureCodeInfo = numbers[0]['imei']
                z.set_serial("im.yixin", featureCodeInfo)
            else:
                z.generate_serial("im.yixin")  # 随机生成手机特征码
                z.toast("随机生成手机特征码")

        self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽

        d.server.adb.cmd(
            "shell",
            "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" +
            slotnum + "号\"").communicate()
        z.sleep(2)

        i = 0
        while i < 2:
            i += 1
            d.server.adb.cmd("shell",
                             "am start -n im.yixin/.activity.WelcomeActivity"
                             ).communicate()  # 拉起易信
            z.sleep(30)

            z.heartbeat()
            if d(text='很抱歉,“易信”已停止运行。').exists:
                d(text='确定').click()
                return 'fail'

            if d(text='立即更新').exists and d(text='下次再说').exists:
                d(text='下次再说').click()

            if d(text='你被服务器禁止登录,详询客服').exists or d(
                    text='接受',
                    resourceId='im.yixin:id/easy_dialog_positive_btn').exists:
                z.toast(u'切换帐号异常,重新补登')
                self.slot.clear(slotnum)  # 清空改卡槽,并补登
                self.repo.BackupInfo(cateId, 'frozen', remarkArr[1],
                                     featureCodeInfo,
                                     '')  # 仓库号,使用中,QQ号,设备号_卡槽号
                return "fail"

            if d(text='消息').exists and d(text='电话').exists and d(
                    text='发现').exists and d(text='通讯录').exists:
                z.toast(u'切换成功')
                return "success"

        z.toast(u'切换失败,重新补登')
        self.slot.clear(slotnum)  # 清空改卡槽,并补登
        self.repo.BackupInfo(cateId, 'normal', remarkArr[1], featureCodeInfo,
                             '')  # 仓库号,使用中,QQ号,设备号_卡槽号
        return "fail"

    def action(self, d, z, args):
        z.toast("正在ping网络是否通畅")
        while True:
            ping = d.server.adb.cmd("shell",
                                    "ping -c 3 baidu.com").communicate()
            print(ping)
            if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                z.toast("开始执行:易信登录模块 有卡槽")
                break
            z.sleep(2)

        serial = d.server.adb.device_serial()
        self.slot = Slot(serial, self.type)
        slotnum = self.slot.getEmpty()  # 取空卡槽

        if slotnum == 0:  # 没有空卡槽的话
            qiehuan_result = self.qiehuan(d, z, args)
            if qiehuan_result == "fail":
                self.action(d, z, args)
        else:

            login_result = self.login(d, z, args)
            if login_result == "fail":
                featureCodeInfo = z.get_serial("im.yixin")
                self.repo.BackupInfo(args["repo_account_id"], 'frozen',
                                     login_result, featureCodeInfo,
                                     '')  # 仓库号,使用中,QQ号,设备号_卡槽号
                self.action(d, z, args)

            elif login_result is None:
                qiehuan_result = self.qiehuan(d, z, args)
                if qiehuan_result == "fail":
                    self.action(d, z, args)

            else:
                featureCodeInfo = z.get_serial("im.yixin")
                # 入库
                self.repo.BackupInfo(args["repo_account_id"], 'using',
                                     login_result, featureCodeInfo,
                                     '%s_%s_%s' %
                                     (d.server.adb.device_serial(), self.type,
                                      slotnum))  # 仓库号,使用中,QQ号,设备号_卡槽号
                # 入卡槽
                self.slot.backup(slotnum,
                                 str(slotnum) + '_' + login_result + '_' +
                                 args["repo_account_id"])  # 设备信息,卡槽号,QQ号

        if (args['time_delay']):
            z.sleep(int(args['time_delay']))
예제 #8
0
class MobilqqLogin3:
    def __init__(self):
        self.type = 'mobileqq'
        self.repo = Repo()
        self.codedll = codeDLL()

    def GetUnique(self):
        nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
        # 生成当前时间
        randomNum = random.randint(0, 1000)
        # 生成的随机整数n,其中0<=n<=100
        if randomNum <= 10:
            randomNum = str(00) + str(randomNum)
        uniqueNum = str(nowTime) + str(randomNum)
        return uniqueNum

    def WebViewBlankPages(self, d, z):
        z.toast("判断是否是滑块")
        Str = d.info  # 获取屏幕大小等信息
        height = float(Str["displayHeight"])
        width = float(Str["displayWidth"])

        W_H = width / height
        screenScale = round(W_H, 2)

        base_dir = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir, "tmp"))
        if not os.path.isdir(base_dir):
            os.mkdir(base_dir)
        sourcePng = os.path.join(base_dir, "%s_s.png" % (self.GetUnique()))

        if screenScale == 0.56:
            left = 115  # 验证码的位置信息
            top = 670
            right = 185
            bottom = 720
        if screenScale == 0.61:
            left = 115  # 验证码的位置信息
            top = 670
            right = 185
            bottom = 720

        d.screenshot(sourcePng)  # 截取整个输入验证码时的屏幕

        img = Image.open(sourcePng)
        box = (left, top, right, bottom)  # left top right bottom
        region = img.crop(box)  # 截取验证码的图片
        # show(region)    #展示资料卡上的信息
        image = region.convert('RGBA')
        # 生成缩略图,减少计算量,减小cpu压力
        image.thumbnail((200, 200))
        max_score = None
        dominant_color = None
        for count, (r, g, b,
                    a) in image.getcolors(image.size[0] * image.size[1]):
            # 跳过纯黑色
            if a == 0:
                continue
            saturation = colorsys.rgb_to_hsv(r / 255.0, g / 255.0,
                                             b / 255.0)[1]
            y = min(
                abs(r * 2104 + g * 4130 + b * 802 + 4096 + 131072) >> 13, 235)
            y = (y - 16.0) / (235 - 16)
            # 忽略高亮色
            if y > 0.9:
                continue

            score = (saturation + 0.1) * count
            if score > max_score:
                max_score = score
                dominant_color = (r, g, b)  # 红绿蓝
        return dominant_color

    def WebViewPlayCode(self, d, z):
        z.toast("非空白页,开始截图打码")

        Str = d.info  # 获取屏幕大小等信息
        height = float(Str["displayHeight"])
        width = float(Str["displayWidth"])
        W_H = width / height
        screenScale = round(W_H, 2)

        base_dir = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir, "tmp"))
        if not os.path.isdir(base_dir):
            os.mkdir(base_dir)
        sourcePng = os.path.join(base_dir, "%s_s.png" % (self.GetUnique()))
        icode = imageCode()
        im_id = ""
        for i in range(0, 1):  # 打码循环
            if i > 0:
                icode.reportError(im_id)

            d.screenshot(sourcePng)  # 截取整个输入验证码时的屏幕
            if screenScale == 0.61:
                p = {
                    "x1": 30 / width,
                    "y1": 200 / height,
                    "x2": 271 / width,
                    "y2": 300 / height
                }
            if screenScale == 0.56:
                p = {
                    "x1": 40 / width,
                    "y1": 270 / height,
                    "x2": 362 / width,
                    "y2": 400 / height
                }
            cropedImg = z.img_crop(sourcePng, p)
            im = open(cropedImg, 'rb')
            codeResult = icode.getCode(im, icode.CODE_TYPE_4_NUMBER_CHAR, 60)
            code = codeResult["Result"]
            im_id = codeResult["Id"]
            os.remove(sourcePng)
            z.heartbeat()
            z.sleep(5)
            if screenScale == 0.61:
                d.click(360, 240)
            if screenScale == 0.56:
                d.click(500, 350)
            z.input(code)
            z.sleep(2)
            if screenScale == 0.61:
                d.click(270, 450)
            if screenScale == 0.56:
                d.click(360, 600)

            while d(className='android.widget.ProgressBar',
                    index=0).exists:  # 网速不给力时,点击完成后仍然在加载时的状态
                z.sleep(2)
            z.sleep(8)

            if not d(textContains='验证码').exists:
                z.toast("机器人打码跳出--")
                break

    # def playCode(self, codeImgObj, type):
    #     z.toast("非网页视图打码")
    #     self.scode = smsCode(d.server.adb.device_serial())
    #     base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, "tmp"))
    #     if not os.path.isdir(base_dir):
    #         os.mkdir(base_dir)
    #     sourcePng = os.path.join(base_dir, "%s_s.png" % (self.GetUnique()))
    #     codePng = os.path.join(base_dir, "%s_c.png" % (self.GetUnique()))
    #     icode = imageCode()
    #     im_id = ""
    #     for i in range(0, 4):  # 打码循环
    #         if i > 0:
    #             icode.reportError(im_id)
    #         obj = d(resourceId='com.tencent.mobileqq:id/name',
    #                  className='android.widget.ImageView')  # 当弹出选择QQ框的时候,定位不到验证码图片
    #         if not obj.exists:
    #             obj = d(index='2', className='android.widget.Image')
    #         obj = obj.info
    #         obj = obj['bounds']  # 验证码处的信息
    #         left = obj["left"]  # 验证码的位置信息
    #         top = obj['top']
    #         right = obj['right']
    #         bottom = obj['bottom']
    #
    #         d.screenshot(sourcePng)  # 截取整个输入验证码时的屏幕
    #
    #         img = Image.open(sourcePng)
    #         box = (left, top, right, bottom)  # left top right bottom
    #         region = img.crop(box)  # 截取验证码的图片
    #
    #         img = Image.new('RGBA', (right - left, bottom - top))
    #         img.paste(region, (0, 0))
    #
    #         img.save(codePng)
    #
    #         with open(codePng, 'rb') as im:
    #             codeResult = icode.getCode(im, icode.CODE_TYPE_4_NUMBER_CHAR, 60)
    #
    #         code = codeResult["Result"]
    #         im_id = codeResult["Id"]
    #         os.remove(sourcePng)
    #         os.remove(codePng)
    #         z.heartbeat()
    #         z.sleep(5)
    #         if type == 0:
    #             d(resourceId='com.tencent.mobileqq:id/name', index='2',
    #                className="android.widget.EditText").set_text(code)
    #         else:
    #             codeImgObj.set_text(code)
    #         z.sleep(3)
    #         if d(descriptionContains='验证', className='android.view.View').exists:
    #             d(descriptionContains='验证', className='android.view.View').click()
    #         else:
    #             d(text='完成', resourceId='com.tencent.mobileqq:id/ivTitleBtnRightText').click()
    #         z.sleep(6)
    #         z.heartbeat()
    #         while d(className='android.widget.ProgressBar', index=0).exists:  # 网速不给力时,点击完成后仍然在加载时的状态
    #             z.sleep(2)
    #         z.sleep(3)
    #         z.heartbeat()
    #         if codeImgObj.exists:
    #             continue
    #         else:
    #             break
    #     z.sleep(5)
    #     if d(textContains='验证码').exists:
    #         return False
    #     else:
    #         return True

    def login(self, d, args, z, numbers):

        QQNumber = numbers[0]['number']  # 即将登陆的QQ号
        QQPassword = numbers[0]['password']

        z.heartbeat()
        d.server.adb.cmd("shell",
                         "pm clear com.tencent.mobileqq").communicate()  # 清除缓存
        d.server.adb.cmd(
            "shell",
            "am start -n com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity"
        ).communicate()  # 拉起来
        z.sleep(5)
        while d(textContains='正在更新数据').exists:
            z.sleep(2)

        z.sleep(15)
        z.heartbeat()
        d.dump(compressed=False)
        if d(text='登 录',
             resourceId='com.tencent.mobileqq:id/btn_login').exists:
            d(text='登 录').click()

        z.sleep(1)
        d(className='android.widget.EditText',
          index=0).click()  # 1918697054----xiake1234.  QQNumber
        z.input(QQNumber)

        z.sleep(1)
        d(resourceId='com.tencent.mobileqq:id/password').click(
        )  # Bn2kJq5l     QQPassword
        z.input(QQPassword)

        z.heartbeat()
        print('QQ号:%s,QQ密码:%s' % (QQNumber, QQPassword))
        d.dump(compressed=False)
        d(text='登 录', resourceId='com.tencent.mobileqq:id/login').click()
        z.sleep(3)
        while d(text='登录中').exists:
            z.sleep(2)
        z.sleep(20)

        z.heartbeat()
        detection_robot = d(index='3', className="android.widget.EditText")
        not_detection_robot = d(resourceId='com.tencent.mobileqq:id/name',
                                index='2',
                                className="android.widget.EditText")
        if detection_robot.exists:  # 需要验证码的情况
            if not self.playCode(detection_robot, 1):
                return False

        if not_detection_robot.exists:
            if not self.playCode(not_detection_robot.exists, 0) == "nothing":
                return False

        if d(className='android.webkit.WebView').exists:
            if self.WebViewBlankPages(d, z)[2] < 200:
                self.WebViewPlayCode(d, z)
            else:
                y = 555
                for r in range(1, 3):
                    d.swipe(155, 703, y, 703)
                    z.sleep(2)
                    if not d(text='验证码',
                             resourceId='com.tencent.mobileqq:id/ivTitleName'
                             ).exists:
                        break
                    else:
                        y += 20

                if d(text='验证码',
                     resourceId='com.tencent.mobileqq:id/ivTitleName'
                     ).exists or d(text='去安全中心').exists:
                    self.repo.BackupInfo(args["repo_cate_id"], 'frozen',
                                         QQNumber, '',
                                         '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                    return False

        z.sleep(5)
        z.heartbeat()
        loginStatusList = z.qq_getLoginStatus(d)
        if loginStatusList is None:
            if d(text='消息').exists and d(text='联系人').exists and d(
                    text='动态').exists:
                loginStatusList = {'success': True}
            elif d(textContains="请在小米神隐模式中将TIM设置为“无限制”。").exists:
                z.toast("我是小米神隐")
                d(text='我知道了').click()
            else:
                loginStatusList = {'success': False}

        loginStatus = loginStatusList['success']
        if loginStatus:
            z.toast("卡槽QQ状态正常,继续执行")
            return True
        else:
            if d(text='去安全中心').exists:
                self.repo.BackupInfo(args["repo_cate_id"], 'frozen', QQNumber,
                                     '', '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

            else:
                self.repo.BackupInfo(args["repo_cate_id"], 'normal', QQNumber,
                                     '', '')

            z.toast("卡槽QQ状态异常,跳过此模块")
            return False

        # if d(text='马上绑定').exists:
        #     self.BindAddressBook(z, d, args)

    def qiehuan(self, d, z, args):
        time_limit = int(args['time_limit'])
        serial = d.server.adb.device_serial()
        self.slot = Slot(serial, self.type)
        slotObj = self.slot.getAvailableSlot(time_limit)  # 没有空卡槽,取2小时没用过的卡槽
        slotnum = None
        if not slotObj is None:
            slotnum = slotObj['id']

        while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\""
            ).communicate()
            z.heartbeat()
            z.sleep(30)
            slotObj = self.slot.getAvailableSlot(time_limit)
            if not slotObj is None:
                slotnum = slotObj['id']
                break

        z.heartbeat()
        d.server.adb.cmd("shell",
                         "pm clear com.tencent.mobileqq").communicate()  # 清除缓存

        d.server.adb.cmd(
            "shell",
            "settings put global airplane_mode_on 1").communicate()  # 开飞行模式
        d.server.adb.cmd(
            "shell",
            "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true"
        ).communicate()
        z.sleep(6)
        z.heartbeat()

        d.server.adb.cmd(
            "shell",
            "settings put global airplane_mode_on 0").communicate()  # 关飞行模式
        d.server.adb.cmd(
            "shell",
            "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false"
        ).communicate()

        z.heartbeat()
        while True:
            ping = d.server.adb.cmd("shell",
                                    "ping -c 3 baidu.com").communicate()
            print(ping)
            if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                break
            z.sleep(2)

        obj = self.slot.getSlotInfo(slotnum)
        remark = obj['remark']
        remarkArr = remark.split("_")
        cateId = ""
        if len(remarkArr) == 3:
            slotInfo = d.server.adb.device_serial(
            ) + '_' + self.type + '_' + slotnum
            cateId = remarkArr[2]
            numbers = self.repo.Getserial(cateId, slotInfo)
            if len(numbers) != 0:
                featureCodeInfo = numbers[0]['imei']
                z.set_serial("com.tencent.mobileqq", featureCodeInfo)

        self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽
        z.sleep(2)

        d.server.adb.cmd(
            "shell",
            "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" +
            slotnum + "号\"").communicate()
        z.sleep(2)
        d.server.adb.cmd(
            "shell",
            "am start -n com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity"
        ).communicate()  # 拉起来
        z.sleep(5)
        while d(textContains='正在更新数据').exists:
            z.sleep(2)
        z.sleep(15)

        z.heartbeat()
        loginStatusList = z.qq_getLoginStatus(d)
        if loginStatusList is None:
            if d(text='消息').exists and d(text='联系人').exists and d(
                    text='动态').exists:
                loginStatusList = {'success': True}
            elif d(textContains="请在小米神隐模式中将TIM设置为“无限制”。").exists:
                z.toast("我是小米神隐")
                d(text='我知道了').click()
                loginStatusList = {'success': True}
            else:
                z.toast("登陆新场景,现无法判断登陆状态")
                loginStatusList = {'success': False}

        loginStatus = loginStatusList['success']
        if loginStatus:
            z.toast("卡槽QQ状态正常,继续执行")
            return True
        else:
            QQnumber = remarkArr[1]
            if d(text='去安全中心').exists:
                self.repo.BackupInfo(cateId, 'frozen', QQnumber, '',
                                     '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

            else:
                self.repo.BackupInfo(cateId, 'normal', QQnumber, '', '')

            self.slot.clear(slotnum)  # 清空改卡槽,并补登
            z.toast("卡槽QQ状态异常,补登陆卡槽")
            return False

    def action(self, d, z, args):
        while True:
            z.toast("正在ping网络是否通畅")
            i = 0
            while i < 200:
                i += 1
                ping = d.server.adb.cmd("shell",
                                        "ping -c 3 baidu.com").communicate()
                print(ping)
                if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                    z.toast("网络通畅。开始执行:普通QQ登录有卡槽")
                    break
                z.sleep(2)
            if i > 200:
                z.toast("网络不通,请检查网络状态")
                if (args["time_delay"]):
                    z.sleep(int(args["time_delay"]))
                return

            z.heartbeat()
            z.generate_serial("com.tencent.mobileqq")  # 随机生成手机特征码
            cate_id = args["repo_cate_id"]

            time_limit1 = args['time_limit1']
            numbers = self.repo.GetAccount(cate_id, time_limit1, 1)
            if len(numbers) == 0:
                d.server.adb.cmd(
                    "shell",
                    "am broadcast -a com.zunyun.zime.toast --es msg \"QQ帐号库%s号仓库无%s分钟未用,开始切换卡槽\""
                    % (cate_id, time_limit1)).communicate()

            serial = d.server.adb.device_serial()
            self.slot = Slot(serial, self.type)
            slotnum = self.slot.getEmpty()  # 取空卡槽
            if slotnum == 0 or len(numbers) == 0:  #没有空卡槽的话
                if self.qiehuan(d, z, args):
                    break

            else:  # 有空卡槽的情况
                d.server.adb.cmd(
                    "shell",
                    "pm clear com.tencent.mobileqq").communicate()  # 清除缓存

                d.server.adb.cmd(
                    "shell",
                    "settings put global airplane_mode_on 1").communicate()
                d.server.adb.cmd(
                    "shell",
                    "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true"
                ).communicate()
                z.sleep(6)
                d.server.adb.cmd(
                    "shell",
                    "settings put global airplane_mode_on 0").communicate()
                d.server.adb.cmd(
                    "shell",
                    "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false"
                ).communicate()
                z.heartbeat()
                while True:
                    ping = d.server.adb.cmd(
                        "shell", "ping -c 3 baidu.com").communicate()
                    print(ping)
                    if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                        break
                    z.sleep(2)

                z.heartbeat()
                if self.login(d, args, z, numbers):
                    z.heartbeat()
                    featureCodeInfo = z.get_serial("com.tencent.mobileqq")
                    self.slot.backup(slotnum,
                                     str(slotnum) + '_' +
                                     numbers[0]['number'] + '_' +
                                     cate_id)  # 设备信息,卡槽号,QQ号
                    self.repo.BackupInfo(
                        cate_id, 'using', numbers[0]['number'],
                        featureCodeInfo,
                        '%s_%s_%s' % (d.server.adb.device_serial(), self.type,
                                      slotnum))  # 仓库号,使用中,QQ号,设备号_卡槽号
                    break

        if args["time_delay"]:
            z.sleep(int(args["time_delay"]))
예제 #9
0
파일: TIMLogin.py 프로젝트: wszg5/studyGit
class TIMLogin:
    def __init__(self):
        self.repo = Repo()
        self.type = 'tim'
        # self.slot = Slot('tim')

    def login(self,d,z,args):
        serial = d.server.adb.device_serial( )
        self.slot = Slot( serial, self.type )
        cateId = args['repo_cate_id']
        name = self.repo.GetMaterial(cateId,120,1)
        name = name[0]['content']
        d.server.adb.cmd("shell", "pm clear com.tencent.tim").communicate()  # 清除缓存
        d.server.adb.cmd("shell","am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity").communicate()  # 拉起来
        time.sleep(8)

        d(text='新用户', resourceId='com.tencent.tim:id/btn_register').click()
        token = self.XunMa.GetToken()
        phoneNumber = self.XunMa.GetPhoneNumber(token)
        print(phoneNumber)
        d(text='请输入你的手机号码', resourceId='com.tencent.tim:id/name').set_text(phoneNumber)
        d(text='下一步', resourceId='com.tencent.tim:id/name').click()
        try:
            vertifyCode = self.XunMa.GetCode(phoneNumber, token)  # 获取验证码
        except Exception:
            d(textContains='重新发送', resourceId='com.tencent.tim:id/name').click()
            vertifyCode = self.XunMa.GetCode(phoneNumber, token)  # 获取验证码

        d(text='请输入短信验证码', resourceId='com.tencent.tim:id/name').set_text(vertifyCode)
        d(textContains='重新发送', resourceId='com.tencent.tim:id/name').click()

        d(text='下一步', resourceId='com.tencent.tim:id/name').click()
        time.sleep(1)
        if d(text='绑定新QQ号码', resourceId='com.tencent.tim:id/action_sheet_button').exists:
            d(text='绑定新QQ号码', resourceId='com.tencent.tim:id/action_sheet_button').click()

        d(resourceId='com.tencent.tim:id/name', className='android.widget.EditText').click()
        z.input(name)
        d(text='完成', resourceId='com.tencent.tim:id/name').click()
        obj = d(resourceId='com.tencent.tim:id/name',className='android.widget.TextView',index=1).info
        info = obj['text']                             #要保存的qq号

        d(text='登录', resourceId='com.tencent.tim:id/name').click()
        time.sleep(6)
        # d.server.adb.cmd("shell", "am force-stop com.tencent.tim").wait()  # 强制停止
        # d.server.adb.cmd("shell",
        #                  "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity").wait()  # 拉起来
        return info



    def action(self, d, z,args):
        serial = d.server.adb.device_serial( )
        self.slot = Slot( serial, self.type )
        time_limit = args['time_limit']
        cate_id = args["repo_cate_id"]
        name = self.slot.getEmpty(d)                    #取空卡槽

        if name ==0:
            name = self.slot.getSlot(d,time_limit)              #没有空卡槽,取2小时没用过的卡槽
            while name==0:                               #2小时没有用过的卡槽也为空的情况
                d.server.adb.cmd("shell", "am broadcast -a com.zunyun.qk.toast --es msg \"卡槽全满,无2小时未用\"").communicate()
                time.sleep(30)
                name = self.slot.getSlot(d,time_limit)

            z.set_mobile_data(False)
            time.sleep(3)
            self.slot.restore(d,name)                      #有2小时没用过的卡槽情况,切换卡槽
            z.set_mobile_data(True)
            time.sleep(8)
            d.server.adb.cmd("shell", "am broadcast -a com.zunyun.qk.toast --es msg \"TIM卡槽切换成功\"").communicate()

            d.server.adb.cmd("shell","am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity").communicate()  # 拉起来
            if d(text='帐号无法登录').exists:
                info = self.login(d,z,args)                                             #帐号无法登陆则登陆,重新注册登陆

                # self.repo.BackupInfo(cate_id, d, name, info)  # 将登陆上的仓库cate_id,设备号d,卡槽号name,qq号info,备份到仓库

                self.slot.backup(d,name,info)                                 #登陆之后备份
            else:
                return

        else:                                     #有空卡槽的情况
            z.set_mobile_data(False)
            time.sleep(2)
            z.set_mobile_data(True)
            time.sleep(8)
            info = self.login(d,z,args)

            # self.repo.BackupInfo(cate_id, d, name, info)  # 将登陆上的仓库cate_id,设备号d,卡槽号name,qq号info,备份到仓库

            self.slot.backup(d,name,info)



        if (args["time_delay"]):
            time.sleep(int(args["time_delay"]))
예제 #10
0
class YiXinRegister:
    def __init__(self):
        self.repo = Repo()
        self.type = 'yixin'
        self.flag = False
        self.number = ''
        self.find = False

    def GenPassword(self, numOfNum=4, numOfLetter=4):
        # 选中numOfNum个数字
        slcNum = [random.choice(string.digits) for i in range(numOfNum)]
        # 选中numOfLetter个字母
        slcLetter = [random.choice(string.lowercase) for i in range(numOfLetter)]
        slcChar = slcLetter + slcNum
        genPwd = ''.join([i for i in slcChar])
        return genPwd

    def register(self, d, z, args, password):
        self.scode = smsCode(d.server.adb.device_serial())
        str = d.info  # 获取屏幕大小等信息
        height = str["displayHeight"]
        width = str["displayWidth"]

        z.toast(u"开始注册")
        d.server.adb.cmd("shell", "pm clear im.yixin").communicate()  # 清除缓存
        d.server.adb.cmd("shell", "am start -n im.yixin/.activity.WelcomeActivity").communicate()  # 拉起易信
        z.sleep(10)
        z.heartbeat()

        if d(resourceId='im.yixin:id/register_btn').exists:  # 点击注册
            d(resourceId='im.yixin:id/register_btn').click()
            z.sleep(2)

        # 取呢称素材库获取注册昵称
        material_cate_id = args['repo_material_id']
        # material_time_limit = args['material_time_limit']
        nicknameLsit = self.repo.GetMaterial(material_cate_id, 0, 1)
        if len(nicknameLsit) == 0:
            d.server.adb.cmd("shell",
                              "am broadcast -a com.zunyun.zime.toast --es msg \"昵称素材库%s号仓库为空\"" % material_cate_id).communicate()
            self.flag = True
            return False

        nickname = nicknameLsit[0]['content']

        while True:
            z.heartbeat()
            z.toast(u'开始获取手机号')

            numberText = d(resourceId='im.yixin:id/register_phone_number_edittext').info['text']  # 将之前消息框的内容删除
            if numberText != '请输入手机号':  # 清空文本框上次输入的号码
                for objText in numberText:
                    d.press.delete()

            # 取号码库获取注册号码
            number_cate_id = args['repo_number_id']
            # number_time_limit = int(args['number_time_limit'])  # 号码提取时间间隔
            exist_numbers = self.repo.GetNumber(number_cate_id, 0, 1, 'exist')
            remain = 1 - len(exist_numbers)
            normal_numbers = self.repo.GetNumber(number_cate_id, 0, remain, 'normal')

            numbers = exist_numbers + normal_numbers
            if len(numbers) == 0:
                d.server.adb.cmd("shell",
                                  "am broadcast -a com.zunyun.zime.toast --es msg \"电话号码%s号仓库为空\"" % number_cate_id).communicate()
                self.flag = True
                return False

            number = numbers[0]["number"]

            if d(resourceId='im.yixin:id/register_phone_number_edittext').exists:
                d(resourceId='im.yixin:id/register_phone_number_edittext').click()

            # try:
            #     PhoneNumber = self.scode.GetPhoneNumber(self.scode.WECHAT_REGISTER, number)  # 获取接码平台手机号码
            # except:
            #     PhoneNumber = None

            PhoneNumber = self.scode.GetPhoneNumber(self.scode.WECHAT_REGISTER)  # 获取接码平台手机号码

            if PhoneNumber is None:
                self.scode.defriendPhoneNumber(PhoneNumber, self.scode.WECHAT_REGISTER)
                z.toast(u'讯码查不无此号,重新获取')
                continue
            else:
                z.toast(u'成功获取到手机号')

            z.input(PhoneNumber)

            if not d(text='中国', resourceId='im.yixin:id/tv_register_country').exists:
                d(resourceId='im.yixin:id/tv_register_country').click()
                z.sleep(1)
                while True:
                    if d(text='中国').exists:
                        d(text='中国').click()
                        break
                    else:
                        d.swipe(width / 2, height * 6 / 7, width / 2, height / 7)

            if d(text='下一步').exists:
                d(text='下一步').click()
                z.sleep(8)

            if d(textContains='该手机号已被注册,是否现在登录').exists:
                d(text='是').click()
                z.sleep(2)

                if d(text='找回密码').exists:
                    d(text='找回密码').click()

                if d(text='下一步').exists:
                    d(text='下一步').click()
                    z.sleep(3)

                self.find = True

            z.heartbeat()
            if d(text='为了验证身份,我们将会发送短信验证码到你的手机').exists:
                self.scode.defriendPhoneNumber(PhoneNumber, self.scode.WECHAT_REGISTER)
                continue

            if d(textContains='验证码短信已发送至').exists:
                break

        try:
            code = self.scode.GetVertifyCode(PhoneNumber, self.scode.WECHAT_REGISTER, 4)  # 获取接码验证码
        except:
            code = ''

        self.scode.defriendPhoneNumber(PhoneNumber, self.scode.WECHAT_REGISTER)
        if code == '':
            z.toast(PhoneNumber + '手机号,获取不到验证码')
            return False

        for codeStr in code:
            z.input(codeStr)

        z.sleep(2)

        if self.find:
            z.input(password)
            z.sleep(2)

            d(text='完成').click()
            z.sleep(5)

        if d(resourceId='im.yixin:id/register_username_edittext').exists:
            d(resourceId='im.yixin:id/register_username_edittext').click()
            z.input(nickname)

        if d(resourceId='im.yixin:id/register_password_edittext').exists:
            d(resourceId='im.yixin:id/register_password_edittext').click()
            z.input(password)

        if d(text='下一步').exists:
            d(text='下一步').click()
            z.sleep(3)

        if d(text='完善信息').exists:
            d(index=1).click()
            z.sleep(1)
            ageArray = ['00后', '95后', '90后', '85后']
            age = ageArray[random.randint(0, 3)]
            if d(text=age).exists:
                d(text=age).click()

            if d(text='开启易信').exists:
                d(text='开启易信').click()
                z.sleep(10)

        if d(text='同意').exists:
            d(text='同意').click()

        while d(text='允许').exists:
            d(text='允许').click()
            z.sleep(2)

        z.heartbeat()
        if d(text='立即更新').exists and d(text='下次再说').exists:
            d(text='下次再说').click()

        if d(text='易信').exists and d(text='发现').exists and d(text='好友').exists and d(text='我').exists:
            z.toast(u'注册成功')
            self.number = PhoneNumber
            return True
        else:
            z.toast(u'注册失败,重新注册')
            return False

    def qiehuan(self, d, z, args):
        z.toast("开始切换卡槽")
        slot_time_limit = int(args['slot_time_limit'])  # 卡槽提取时间间隔
        try:
            slotObj = self.slot.getAvailableSlot(slot_time_limit)  # 取空卡槽,取N小时没用过的卡槽
        except:
            z.toast(u'获取卡槽异常')
            return False

        slotnum = None
        if not slotObj is None:
            slotnum = slotObj['id']

        while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
            d.server.adb.cmd("shell",
                              "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\"").communicate()
            z.heartbeat()
            z.sleep(10)
            slotObj = self.slot.getAvailableSlot(slot_time_limit)
            if not slotObj is None:
                slotnum = slotObj['id']

        z.heartbeat()
        print(slotnum)

        obj = self.slot.getSlotInfo(slotnum)
        remark = obj['remark']
        remarkArr = remark.split("_")
        cateId = ''
        featureCodeInfo = ''
        if len(remarkArr) == 3:
            slotInfo = d.server.adb.device_serial() + '_' + self.type + '_' + slotnum
            cateId = remarkArr[2]
            numbers = self.repo.Getserial(cateId, slotInfo)
            if len(numbers) > 0:
                featureCodeInfo = numbers[0]['imei']
                z.set_serial("im.yixin", featureCodeInfo)

        d.server.adb.cmd("shell", "pm clear im.yixin").communicate()  # 清除缓存

        self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽

        d.server.adb.cmd("shell",
                          "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" + slotnum + "号\"").communicate()
        z.sleep(2)

        d.server.adb.cmd("shell", "am start -n im.yixin/.activity.WelcomeActivity").communicate()  # 拉起易信
        z.sleep(10)
        z.heartbeat()

        if d(text='很抱歉,“易信”已停止运行。').exists:
            d(text='确定').click()

        d.server.adb.cmd("shell", "am start -n im.yixin/.activity.WelcomeActivity").communicate()  # 拉起易信
        z.sleep(15)
        z.heartbeat()

        if d(text='同意').exists:
            d(text='同意').click()

        if d(text='立即更新').exists and d(text='下次再说').exists:
            d(text='下次再说').click()

        if d(text='你被服务器禁止登录,详询客服').exists:
            z.toast(u'切换帐号异常,重新补登')
            self.slot.clear(slotnum)  # 清空改卡槽,并补登
            if cateId != '':
                self.repo.BackupInfo(cateId, 'frozen', remarkArr[1], featureCodeInfo, '')  # 仓库号,使用中,QQ号,设备号_卡槽号
            return False

        if d(text='易信').exists and d(text='发现').exists and d(text='好友').exists and d(text='我').exists:
            self.flag = False
            return True
        else:
            z.toast(u'切换失败,重新补登')
            self.slot.clear(slotnum)  # 清空改卡槽,并补登
            if cateId != '':
                self.repo.BackupInfo(cateId, 'normal', remarkArr[1], featureCodeInfo, '')  # 仓库号,使用中,QQ号,设备号_卡槽号
            return False

    def action(self, d, z, args):

        while True:
            z.toast(u"正在ping网络是否通畅")
            while True:
                ping = d.server.adb.cmd("shell", "ping -c 3 baidu.com").communicate()
                print(ping)
                if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                    z.toast(u"开始执行:易信注册模块 有卡槽")
                    break
                z.sleep(2)

            z.generate_serial("im.yixin")  # 随机生成手机特征码
            z.toast(u"随机生成手机特征码")

            serial = d.server.adb.device_serial()
            self.slot = Slot(serial, self.type)
            slotnum = self.slot.getEmpty()  # 取空卡槽

            if slotnum == 0 or self.flag:  # 没有空卡槽的话
                if self.qiehuan(d, z, args):
                    z.toast(u'切换成功,程序退出。')
                    break

            else:

                password = self.GenPassword()
                if self.register(d, z, args, password):
                    if self.number != '':
                        # 入库
                        featureCodeInfo = z.get_serial("im.yixin")
                        self.repo.RegisterAccount(self.number, password, "", args['repo_account_id'], "using", featureCodeInfo, '%s_%s_%s' % (
                                                       d.server.adb.device_serial(), self.type, slotnum))
                        # 入卡槽
                        self.slot.backup(slotnum, str(slotnum) + '_' + self.number + '_' + args['repo_account_id'])  # 设备信息,卡槽号,QQ号

                        break

        if (args['time_delay']):
            z.sleep(int(args['time_delay']))
예제 #11
0
class YiXinLoginHaveSolt:
    def __init__(self):
        self.repo = Repo()
        self.type = 'yixin'
        self.flag = False
        self.featureCodeInfo = ''
        self.PhoneNumber = ''

    def login(self, d, z, args):
        z.toast("开始登录")
        d.server.adb.cmd("shell", "pm clear im.yixin").communicate()  # 清除缓存
        d.server.adb.cmd("shell", "am start -n im.yixin/.activity.WelcomeActivity").communicate()  # 拉起易信
        z.sleep(int(args['pull_up_time']))
        z.heartbeat()
        if d(text='很抱歉,“易信”已停止运行。').exists:
            if d(text='确定').exists:
                d(text='确定').click()
            if d(text='取消').exists:
                d(text='取消').click()
            return False

        # d.server.adb.cmd("shell", "am force-stop im.yixin").communicate()  # 强制停止
        # d.server.adb.cmd("shell", "am start -n im.yixin/.activity.WelcomeActivity").communicate()  # 拉起易信
        # z.sleep(5)
        # z.heartbeat()
        # if d(text='很抱歉,“易信”已停止运行。').exists:
        #     d(text='确定').click()
        #     return 'fail'

        if d(text='接受', resourceId='im.yixin:id/easy_dialog_positive_btn').exists:
            d(text='接受', resourceId='im.yixin:id/easy_dialog_positive_btn').click()
            z.sleep(2)

        if d(resourceId='im.yixin:id/login_btn').exists:
            d(resourceId='im.yixin:id/login_btn').click()
            z.sleep(2)

        if d(resourceId='im.yixin:id/login_btn').exists:
            d(resourceId='im.yixin:id/login_btn').click()
            z.sleep(2)

        z.toast(u"开始获取手机号码")

        cate_id = args["repo_account_id"]
        account_time_limit = args['account_time_limit']
        numbers = self.repo.GetAccount(cate_id, account_time_limit, 1)
        if len(numbers) == 0:
            z.heartbeat()
            d.server.adb.cmd("shell", "am broadcast -a com.zunyun.zime.toast --es msg \"QQ帐号库%s号仓库无%s分钟未用,开始切换卡槽\"" % (cate_id, account_time_limit)).communicate()
            self.flag = True
            return False


        featureCodeInfo = numbers[0]['imei']
        if not featureCodeInfo is None:
            z.set_serial("im.yixin", featureCodeInfo)
        else:
            z.generate_serial("im.yixin")  # 随机生成手机特征码
            self.featureCodeInfo = z.get_serial("im.yixin")

        PhoneNumber = numbers[0]['number']  # 即将登陆的QQ号
        Password = numbers[0]['password']
        self.PhoneNumber = PhoneNumber

        if d(resourceId='im.yixin:id/editUserid').exists:
            d(resourceId='im.yixin:id/editUserid').click.bottomright()
            z.sleep(1)
            d(resourceId='im.yixin:id/editUserid').click()
            z.input(PhoneNumber)

        if d(resourceId='im.yixin:id/editPassword').exists:
            d(resourceId='im.yixin:id/editPassword').click.bottomright()
            z.sleep(1)
            d(resourceId='im.yixin:id/editPassword').click()
            z.input(Password)

        if d(resourceId='im.yixin:id/btn_login').exists:
            d(resourceId='im.yixin:id/btn_login').click()
            z.sleep(15)

        z.heartbeat()
        if d(text='同意').exists:
            d(text='同意').click()

        while d(text='允许').exists:
            d(text='允许').click()
            z.sleep(2)

        z.sleep(int(args["pull_up_time"]))
        z.heartbeat()
        if d(text='立即更新').exists and d(text='下次再说').exists:
            d(text='下次再说').click()

        if d(text='易信').exists and d(text='发现').exists and d(text='好友').exists and d(text='我').exists:
            z.toast(u'登录成功')
            return True
        else:
            z.toast(u'登录失败,重新登录')
            return False

    def qiehuan(self, d, z, args):
        z.toast("开始切换卡槽")
        slot_time_limit = int(args['slot_time_limit'])  # 卡槽提取时间间隔
        try:
            slotObj = self.slot.getAvailableSlot(slot_time_limit)  # 取空卡槽,取N小时没用过的卡槽
        except:
            z.toast(u'获取卡槽异常')
            return False

        slotnum = None
        if not slotObj is None:
            slotnum = slotObj['id']

        while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
            d.server.adb.cmd("shell",
                              "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\"").communicate()
            z.heartbeat()
            z.sleep(10)
            slotObj = self.slot.getAvailableSlot(slot_time_limit)
            if not slotObj is None:
                slotnum = slotObj['id']

        z.heartbeat()
        print(slotnum)

        obj = self.slot.getSlotInfo(slotnum)
        remark = obj['remark']
        remarkArr = remark.split("_")
        cateId = ''
        if len(remarkArr) == 3:
            slotInfo = d.server.adb.device_serial() + '_' + self.type + '_' + slotnum
            cateId = remarkArr[2]
            numbers = self.repo.Getserial(cateId, slotInfo)
            if len(numbers) > 0:
                featureCodeInfo = numbers[0]['imei']
                if not featureCodeInfo is None:
                    z.set_serial("im.yixin", featureCodeInfo)
                else:
                    z.generate_serial("im.yixin")  # 随机生成手机特征码
                    self.featureCodeInfo = z.get_serial("im.yixin")

        d.server.adb.cmd("shell", "pm clear im.yixin").communicate()  # 清除缓存

        self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽

        d.server.adb.cmd("shell",
                          "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" + slotnum + "号\"").communicate()
        z.sleep(2)

        d.server.adb.cmd("shell", "am start -n im.yixin/.activity.WelcomeActivity").communicate()  # 拉起易信
        z.sleep(int(args['pull_up_time']))
        z.heartbeat()

        if d(text='很抱歉,“易信”已停止运行。').exists:
            if d(text='确定').exists:
                d(text='确定').click()
            if d(text='取消').exists:
                d(text='取消').click()

        d.server.adb.cmd("shell", "am start -n im.yixin/.activity.WelcomeActivity").communicate()  # 拉起易信
        z.sleep(int(args['pull_up_time']))
        z.heartbeat()

        if d(text='同意').exists:
            d(text='同意').click()

        z.sleep(int(args["pull_up_time"]))
        z.heartbeat()

        if d(text='立即更新').exists and d(text='下次再说').exists:
            d(text='下次再说').click()

        if d(text='你被服务器禁止登录,详询客服').exists or d(textContains='您的帐号暂时无法使用').exists:
            z.toast(u'切换帐号已被冻结,重新补登')
            self.slot.clear(slotnum)  # 清空改卡槽,并补登
            if cateId != '':
                self.repo.BackupInfo(cateId, 'frozen', remarkArr[1], self.featureCodeInfo, '')  # 仓库号,使用中,QQ号,设备号_卡槽号
            return False

        if d(text='易信').exists and d(text='发现').exists and d(text='好友').exists and d(text='我').exists:
            return True
        else:
            z.toast(u'切换失败,重新补登')
            self.slot.clear(slotnum)  # 清空改卡槽,并补登
            if cateId != '':
                self.repo.BackupInfo(cateId, 'normal', remarkArr[1], self.featureCodeInfo, '')  # 仓库号,使用中,QQ号,设备号_卡槽号
            return False

    def action(self, d, z, args):

        while True:
            z.toast("正在ping网络是否通畅")
            while True:
                ping = d.server.adb.cmd("shell", "ping -c 3 baidu.com").communicate()
                print(ping)
                if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                    z.toast("开始执行:易信登录模块 有卡槽")
                    break
                z.sleep(2)

            serial = d.server.adb.device_serial()
            self.slot = Slot(serial, self.type)
            slotnum = self.slot.getEmpty()  # 取空卡槽

            if slotnum == 0 or self.flag:  # 没有空卡槽的话

                if self.qiehuan(d, z, args):
                    z.toast(u'切换成功,程序退出。')
                    break
            else:

                if self.login(d, z, args):

                    self.repo.BackupInfo(args["repo_account_id"], 'using', self.PhoneNumber, self.featureCodeInfo, '%s_%s_%s' % (
                                                       d.server.adb.device_serial(), self.type, slotnum))  # 仓库号,使用中,QQ号,设备号_卡槽号

                    self.slot.backup(slotnum, str(slotnum) + '_' + self.PhoneNumber + '_' + args['repo_account_id'])  # 设备信息,卡槽号,QQ号
                    break

                else:
                    if self.PhoneNumber != '':
                        if d(textContains='您的帐号暂时无法使用').exists:
                            self.repo.BackupInfo(args["repo_account_id"], 'frozen', self.PhoneNumber, '', '')  # 仓库号,使用中,QQ号
                        else:
                            self.repo.BackupInfo(args["repo_account_id"], 'normal', self.PhoneNumber, '', '')  # 仓库号,使用中,QQ号

                self.PhoneNumber = ''

        if (args['time_delay']):
            z.sleep(int(args['time_delay']))
예제 #12
0
class QLLogin:

    def __init__(self):
        self.repo = Repo()
        self.type = 'qqlite'

    def GetUnique(self):
        nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S");  # 生成当前时间
        randomNum = random.randint(0, 1000);  # 生成的随机整数n,其中0<=n<=100
        if randomNum <= 10:
            randomNum = str(00) + str(randomNum);
        uniqueNum = str(nowTime) + str(randomNum);
        return uniqueNum

    def LoginPlayCode(self, d, z):
        self.scode = smsCode( d.server.adb.device_serial( ) )
        base_dir = os.path.abspath( os.path.join( os.path.dirname( __file__ ), os.path.pardir, "tmp" ) )
        if not os.path.isdir( base_dir ):
            os.mkdir( base_dir )
        sourcePng = os.path.join( base_dir, "%s_s.png" % (self.GetUnique( )) )
        codePng = os.path.join( base_dir, "%s_c.png" % (self.GetUnique( )) )
        detection_robot = d( index='3', className="android.widget.EditText" )
        not_detection_robot = d( index='2', className="android.widget.EditText" )
        if detection_robot.exists or not_detection_robot.exists:  # 需要验证码的情况
            icode = imageCode( )
            im_id = ""
            for i in range( 0, 4 ):  # 打码循环
                if i > 0:
                    icode.reportError( im_id )
                obj = d( resourceId='com.tencent.qqlite:id/0',
                         className='android.widget.ImageView' )  # 当弹出选择QQ框的时候,定位不到验证码图片
                if not obj.exists:
                    obj = d( index='2', className='android.widget.Image' )
                obj = obj.info
                obj = obj['bounds']  # 验证码处的信息
                left = obj["left"]  # 验证码的位置信息
                top = obj['top']
                right = obj['right']
                bottom = obj['bottom']

                d.screenshot( sourcePng )  # 截取整个输入验证码时的屏幕

                img = Image.open( sourcePng )
                box = (left, top, right, bottom)  # left top right bottom
                region = img.crop( box )  # 截取验证码的图片

                img = Image.new( 'RGBA', (right - left, bottom - top) )
                img.paste( region, (0, 0) )

                img.save( codePng )
                im = open( codePng, 'rb' )

                codeResult = icode.getCode( im, icode.CODE_TYPE_4_NUMBER_CHAR, 60 )

                code = codeResult["Result"]
                im_id = codeResult["Id"]
                os.remove( sourcePng )
                os.remove( codePng )
                z.heartbeat( )
                z.sleep( 5 )
                if not_detection_robot.exists:
                    d( resourceId='com.tencent.qqlite:id/0', index='2',
                       className="android.widget.EditText" ).set_text( code )
                else:
                    detection_robot.set_text( code )
                z.sleep( 3 )
                if d( descriptionContains='验证', className='android.view.View' ).exists:
                    d( descriptionContains='验证', className='android.view.View' ).click( )
                else:
                    d( text='完成', resourceId='com.tencent.qqlite:id/ivTitleBtnRightText' ).click( )
                z.sleep( 5 )
                z.heartbeat( )
                while d( className='android.widget.ProgressBar', index=0 ).exists:  # 网速不给力时,点击完成后仍然在加载时的状态
                    z.sleep( 2 )
                z.heartbeat( )
                if detection_robot.exists or not_detection_robot.exists:
                    continue
                else:
                    break
            z.sleep( 5 )
            if d( textContains='验证码' ).exists:
                return "no"
            else:
                return "yes"
        else:
            return "no"

    def BindAddressBook(self, z, d, args):
        z.toast( "点击启用" )
        self.scode = smsCode( d.server.adb.device_serial( ) )
        d( text='启用' ).click( )
        while d( text='验证手机号码' ).exists:

            PhoneNumber = None
            j = 0
            while PhoneNumber is None:
                j += 1
                if j == 2:
                    z.toast( '取不到手机号码' )
                    if (args["time_delay"]):
                        z.sleep( int( args["time_delay"] ) )
                    return
                PhoneNumber = self.scode.GetPhoneNumber( self.scode.QQ_CONTACT_BIND )  # 获取接码平台手机号码
                z.heartbeat( )


            if not d( textContains='+86' ).exists:
                d( description='点击选择国家和地区' ).click( )
                if d( text='中国' ).exists:
                    d( text='中国' ).click( )
                else:
                    str = d.info  # 获取屏幕大小等信息
                    height = str["displayHeight"]
                    width = str["displayWidth"]
                    d.click(width * 5 / 12, height * 5 / 32)
                    z.sleep(1.5)
                    z.input('中国')
                    z.sleep(2)
                    d(text='+86').click()

            z.input(PhoneNumber)
            z.sleep(1.5)
            if d(text='下一步').exists:
                d(text='下一步').click()
                z.sleep(3)

            while d( text='正在发送请求' ).exists:
                z.sleep( 2 )
            z.sleep(2)
            z.heartbeat( )
            if d( text='确定' ).exists:
                d( text='确定' ).click( )
                z.sleep( 2 )
            code = self.scode.GetVertifyCode( PhoneNumber, self.scode.QQ_CONTACT_BIND, '4' )  # 获取接码验证码
            self.scode.defriendPhoneNumber( PhoneNumber, self.scode.QQ_CONTACT_BIND )
            if code == '':
                z.toast( PhoneNumber + '手机号,获取不到验证码' )
                if d( text='返回' ).exists:
                    d( text='返回' ).click( )
                if not d( textContains='中国' ).exists:
                    if d( text='返回' ).exists:
                        d( text='返回' ).click( )
                if d( className='android.view.View', descriptionContains='删除' ).exists:
                    d( className='android.view.View', descriptionContains='删除' ).click( )
                continue
            z.heartbeat( )
            z.input( code )
            if d( text='下一步' ).exists:
                d( text='下一步' ).click( )
                z.sleep(1.5)
            if d(text='好').exists:
                d(text='好').click()
            z.sleep(5)
            break

    def login(self,d,args,z):
        z.heartbeat()
        Str = d.info  # 获取屏幕大小等信息
        height = float( Str["displayHeight"] )
        width = float( Str["displayWidth"] )
        W_H = width / height
        screenScale = round( W_H, 2 )

        cate_id = args["repo_cate_id"]
        time_limit1 = args['time_limit1']
        numbers = self.repo.GetAccount( cate_id, time_limit1, 1 )
        while len( numbers ) == 0:
            z.heartbeat( )
            d.server.adb.cmd( "shell", "am broadcast -a com.zunyun.zime.toast --es msg \"QQ帐号库%s号仓库无%s分钟未用,开始切换卡槽\"" % (
            cate_id, time_limit1) ).communicate( )
            z.sleep( 2 )
            return 0

        QQNumber = numbers[0]['number']  # 即将登陆的QQ号
        QQPassword = numbers[0]['password']
        z.sleep( 1 )
        z.heartbeat( )
        d.server.adb.cmd("shell", "pm clear com.tencent.qqlite").communicate( )  # 清除缓存

        # d.server.adb.cmd("shell",
        #                   "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity" ).communicate( )  # 拉起来
        z.server.adb.run_cmd( "shell", "am start -n com.tencent.qqlite/com.tencent.mobileqq.activity.SplashActivity" )
        z.sleep(5)
        while d( textContains='正在更新数据' ).exists:
            z.sleep( 2 )
        z.sleep(3)
        z.heartbeat( )
        d.dump(compressed=False)
        if d(text='登 录',resourceId='com.tencent.qqlite:id/btn_login').exists:
            z.toast("控件点击")
            d( text='登 录' ).click()
        else:
            if screenScale == 0.61:
                d.click(140, 788)
            if screenScale == 0.56:
                d.click(186, 1128)
        z.sleep( 1 )
        # d(className='android.widget.EditText', index=0).set_text(QQNumber)  # 1918697054----xiake1234.  QQNumber
        d(className='android.widget.EditText', index=0).click()  # 1918697054----xiake1234.  QQNumber
        z.input( QQNumber )

        z.sleep( 1 )
        # d(resourceId='com.tencent.mobileqq:id/password').set_text(QQPassword)  # Bn2kJq5l     QQPassword
        d(resourceId='com.tencent.qqlite:id/password').click()  # Bn2kJq5l     QQPassword
        z.input( QQPassword )
        z.heartbeat()
        logger = util.logger
        print('QQ号:%s,QQ密码:%s' % (QQNumber, QQPassword))
        d.dump(compressed=False )
        d( text='登 录', resourceId='com.tencent.qqlite:id/login' ).click( )
        z.sleep(1)
        while d(text='登录中').exists:
            z.sleep(2)
        z.sleep(5)
        z.heartbeat()

        not_detection_robot = d(resourceId='com.tencent.qqlite:id/0',index='2', className="android.widget.EditText" )
        if not_detection_robot.exists:
            playCodeResult = self.LoginPlayCode( d, z )  # 打验证码
        elif d( text='QQ轻聊版', resourceId='com.tencent.qqlite:id/0',className='android.widget.TextView').exists or d( text='启用' ).exists:
            return QQNumber
        else:
            self.repo.BackupInfo( cate_id, 'frozen', QQNumber, '', '' )  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
            z.toast( "卡槽QQ状态异常,跳过此模块" )
            return "nothing"

        if playCodeResult == "no":
            return "nothing"

        z.sleep(5)
        z.heartbeat()
        if d( text='启用' ).exists:
            # self.BindAddressBook(z, d, args)
            return QQNumber

        if d(text='QQ轻聊版', resourceId='com.tencent.qqlite:id/0',className='android.widget.TextView').exists:
            z.toast("卡槽QQ状态正常,继续执行")
            return QQNumber
        else:
            self.repo.BackupInfo( cate_id, 'frozen', QQNumber, '', '' )  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
            z.toast( "卡槽QQ状态异常,跳过此模块" )
            return "nothing"


    def qiehuan(self,d,z,args):
        time_limit = int(args['time_limit'])
        cate_id = args["repo_cate_id"]
        serial = d.server.adb.device_serial( )
        self.slot = Slot( serial, self.type )
        slotObj = self.slot.getAvailableSlot(time_limit)  # 没有空卡槽,取2小时没用过的卡槽
        while slotObj is None:  # 2小时没有用过的卡槽也为空的情况
            d.server.adb.cmd("shell",
                             "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\"").communicate()
            z.heartbeat()
            z.sleep(10)
            slotObj = self.slot.getAvailableSlot( time_limit )  # 没有空卡槽,取2小时没用过的卡槽

        if not slotObj is None:
            slotnum = slotObj['id']
        z.heartbeat()
        d.server.adb.cmd("shell", "pm clear com.tencent.qqlite").communicate()  # 清除缓存

        d.server.adb.cmd("shell", "settings put global airplane_mode_on 1").communicate()
        d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true").communicate()
        z.sleep(6)
        z.heartbeat()
        d.server.adb.cmd("shell", "settings put global airplane_mode_on 0").communicate()
        d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false").communicate()
        obj = self.slot.getSlotInfo( slotnum )
        remark = obj['remark']
        remarkArr = remark.split( "_" )
        if len(remarkArr) == 4:
            featureCodeInfo = remarkArr[2]
            z.set_serial( "com.tencent.qqlite", featureCodeInfo )
        self.slot.restore( slotnum )  # 有time_limit分钟没用过的卡槽情况,切换卡槽
        z.heartbeat()
        z.toast( "正在ping网络是否通畅" )
        while True:
            ping = d.server.adb.cmd("shell", "ping -c 3 baidu.com").communicate()
            print(ping)
            if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                break
            z.sleep(2)

        d.server.adb.cmd("shell", "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" + str(slotnum) + "号\"").communicate()
        z.sleep(2)
        # d.server.adb.cmd("shell", "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity").communicate()  # 拉起来
        z.server.adb.run_cmd( "shell", "am start -n com.tencent.qqlite/com.tencent.mobileqq.activity.SplashActivity" )

        z.sleep( 5 )
        while d( textContains='正在更新数据' ).exists:
            z.sleep( 2 )
        z.sleep( 3 )
        z.heartbeat()
        if d(text='QQ轻聊版', resourceId='com.tencent.qqlite:id/0',className='android.widget.TextView').exists.exists or d( text='启用' ).exists:
            z.toast( "卡槽QQ切换成功,继续执行" )
        else:
            obj = self.slot.getSlotInfo( slotnum )
            remark = obj['remark']
            remarkArr = remark.split( "_" )
            QQnumber = remarkArr[1]
            self.repo.BackupInfo( cate_id, 'frozen', QQnumber, '', '' )  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
            self.slot.clear( slotnum )  # 清空改卡槽,并补登
            z.toast( "卡槽QQ状态异常,补登陆卡槽" )
            self.action( d, z, args )


    def action(self,d,z,args):

        z.generate_serial("com.tencent.qqlite")  # 随机生成手机特征码
        z.toast("随机生成手机特征码")

        time_limit = int( args['time_limit'] )
        cate_id = args["repo_cate_id"]
        serial = d.server.adb.device_serial( )
        self.slot = Slot( serial, self.type )
        slotnum = self.slot.getEmpty( )  # 取空卡槽
        if slotnum == 0:  # 没有空卡槽的话
            slotObj = self.slot.getAvailableSlot( time_limit )  # 取空卡槽,取2小时没用过的卡槽
            if not slotObj is None:
                slotnum = slotObj['id']
            print( slotnum )
            while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
                d.server.adb.cmd( "shell",
                                  "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\"" ).communicate( )
                z.heartbeat( )
                z.sleep( 10 )
                slotObj = self.slot.getAvailableSlot( time_limit )
                if not slotObj is None:
                    slotnum = slotObj['id']
            z.heartbeat()
            d.server.adb.cmd("shell", "pm clear com.tencent.qqlite" ).communicate()  # 清除缓存

            d.server.adb.cmd("shell", "settings put global airplane_mode_on 1").communicate() #开数据流量
            d.server.adb.cmd("shell","am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true").communicate()#开飞行模式
            z.sleep(6)
            z.heartbeat()
            d.server.adb.cmd("shell", "settings put global airplane_mode_on 0").communicate() # 关数据流量
            d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false").communicate()#开飞行模式

            obj = self.slot.getSlotInfo( slotnum )
            remark = obj['remark']
            remarkArr = remark.split( "_" )
            if len( remarkArr ) == 4:
                featureCodeInfo = remarkArr[2] + remarkArr[3]
                print( featureCodeInfo )
                z.set_serial( "com.tencent.qqlite", featureCodeInfo )
            z.set_serial( "com.tencent.qqlite", featureCodeInfo )
            self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽

            z.heartbeat()
            z.toast("正在ping网络是否通畅")
            while True:
                ping = d.server.adb.cmd("shell", "ping -c 3 baidu.com").communicate()
                print(ping)
                if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                    break
                z.sleep( 2 )

            d.server.adb.cmd( "shell",
                              "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" + slotnum + "号\"" ).communicate( )

            z.sleep( 2 )
            # d.server.adb.cmd( "shell",
            #                   "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity" ).communicate( )  # 拉起来
            z.server.adb.run_cmd( "shell", "am start -n com.tencent.qqlite/com.tencent.mobileqq.activity.SplashActivity" )

            z.sleep(5)
            while d( textContains='正在更新数据' ).exists:
                z.sleep( 2 )
            z.sleep( 3 )
            z.heartbeat()
            if d(text='QQ轻聊版', resourceId='com.tencent.qqlite:id/0',className='android.widget.TextView').exists or d( text='启用' ).exists:
                z.toast("卡槽QQ切换成功,继续执行")
            else:
                obj = self.slot.getSlotInfo( slotnum )
                remark = obj['remark']
                remarkArr = remark.split( "_" )
                QQnumber = remarkArr[1]
                self.repo.BackupInfo( cate_id, 'frozen', QQnumber, '', '' )  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                self.slot.clear( slotnum )  # 清空改卡槽,并补登
                z.toast( "卡槽QQ状态异常,补登陆卡槽" )
                self.action( d, z, args )

        else:  # 有空卡槽的情况
            d.server.adb.cmd( "shell", "pm clear com.tencent.qqlite" ).communicate( )  # 清除缓存

            d.server.adb.cmd("shell", "settings put global airplane_mode_on 1").communicate()
            d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true").communicate()
            z.sleep(3)
            d.server.adb.cmd("shell", "settings put global airplane_mode_on 0").communicate()
            d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false").communicate()
            z.heartbeat( )
            z.toast( "正在ping网络是否通畅" )
            while True:
                ping = d.server.adb.cmd( "shell", "ping -c 3 baidu.com" ).communicate( )
                print( ping )
                if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                    break
                z.sleep( 2 )
            serialinfo = d.server.adb.device_serial( )
            # print('登陆时的serial%s'%serialinfo)
            z.heartbeat( )
            QQnumber = self.login( d, args, z )
            if QQnumber == 'nothing':
                self.slot.clear( slotnum )  # 清空改卡槽,并补登
                self.action( d, z, args )
            elif QQnumber == 0:
                z.toast( "仓库为空,无法登陆。开始切换卡槽" )
                self.qiehuan( d, z, args )
            elif QQnumber is None:
                return
            else:
                z.heartbeat()
                featureCodeInfo = z.get_serial( "com.tencent.qqlite" )
                print(featureCodeInfo)
                self.slot.backup( slotnum, str( slotnum ) + '_' + QQnumber + "_" + featureCodeInfo)  # 设备信息,卡槽号,QQ号
                self.repo.BackupInfo( cate_id, 'using', QQnumber, serialinfo, '%s_%s_%s' % (
                    d.server.adb.device_serial( ), self.type, slotnum) )  # 仓库号,使用中,QQ号,设备号_卡槽号


        if (args["time_delay"]):
            time.sleep(int(args["time_delay"]))
예제 #13
0
class QQMailLogin:
    def __init__(self):
        self.repo = Repo()
        self.type = 'qqmail'

    def GetUnique(self):
        nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")  # 生成当前时间
        randomNum = random.randint(0, 1000)  # 生成的随机整数n,其中0<=n<=100
        if randomNum <= 10:
            randomNum = str(00) + str(randomNum)
        uniqueNum = str(nowTime) + str(randomNum)
        return uniqueNum

    def againLogin(self, account, password, d, z, height):
        if d(text="确定", className="android.widget.Button").exists or d(
                text="重新输入", className="android.widget.Button").exists:
            if d(text="确定", className="android.widget.Button").exists:
                d(text="确定", className="android.widget.Button").click()
            else:
                d(text="重新输入", className="android.widget.Button").click()
            time.sleep(1)
            self.input(z, height, password)
            time.sleep(1)
            if d(resourceId="com.tencent.androidqqmail:id/a_").exists:
                d(resourceId="com.tencent.androidqqmail:id/a_").click()
                time.sleep(8)
            while True:
                if d(textContains="验证中"):
                    time.sleep(3)
                else:
                    break
            if d(resourceId='com.tencent.androidqqmail:id/h'
                 ).exists:  # 判断是否要填写独立密码
                self.input(z, height, "Abc" + account)
                z.sleep(1)
                if d(text='确定').exists:
                    d(text='确定').click()
                z.sleep(5)

            while d(resourceId='com.tencent.androidqqmail:id/a16'
                    ).exists:  # 出现验证码
                picObj = d(resourceId='com.tencent.androidqqmail:id/a19',
                           index=0)
                code = self.palyCode(d, z, picObj)
                if code == "":
                    return False
                if d(resourceId='com.tencent.androidqqmail:id/a17').exists:
                    d(resourceId='com.tencent.androidqqmail:id/a17').click()
                self.input(z, height, code)
                if d(resourceId='com.tencent.androidqqmail:id/a_'
                     ).exists:  # 点击登陆
                    d(resourceId='com.tencent.androidqqmail:id/a_').click()
                z.sleep(8)

            if d(resourceId='com.tencent.androidqqmail:id/h'
                 ).exists:  # 判断是否要填写独立密码
                self.input(z, height, "Abc" + account)
                z.sleep(1)
                if d(text='确定').exists:
                    d(text='确定').click()
            while True:
                if d(textContains="验证中"):
                    time.sleep(3)
                else:
                    break
            if d(textContains='你有多个应用同时收到').exists:
                d(text='确定').click()
                z.sleep(2)

            if d(text='收件箱​').exists:
                z.toast(u"登录成功。退出模块")
                # d.server.adb.cmd("shell", "am force-stop com.tencent.androidqqmail").wait()  # 强制停止
                return True
            else:
                if d(textContains='帐号或密码错误').exists:
                    z.toast(u"帐号或密码错误")
                    return False
                elif d(textContains="未开启IMAP服务").exists:
                    z.toast(u"未开启IMAP服务,标记为异常")
                    self.repo.BackupInfo(args["repo_account_id"], 'exception',
                                         account, '',
                                         '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                    return False

    def input(self, z, height, text):
        if height > 888:
            z.input(text)
        else:
            z.cmd("shell",
                  "am broadcast -a ZY_INPUT_TEXT --es text \\\"%s\\\"" % text)

    def palyCode(self, d, z, picObj):
        self.scode = smsCode(d.server.adb.device_serial())
        base_dir = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir, "tmp"))
        if not os.path.isdir(base_dir):
            os.mkdir(base_dir)
        sourcePng = os.path.join(base_dir, "%s_s.png" % (self.GetUnique()))
        codePng = os.path.join(base_dir, "%s_c.png" % (self.GetUnique()))
        icode = imageCode()
        im_id = ""
        code = ""
        for i in range(0, 2):  # 打码循环
            # if i > 0:
            #     icode.reportError(im_id)
            obj = picObj.info
            obj = obj['bounds']  # 验证码处的信息
            left = obj["left"]  # 验证码的位置信息
            top = obj['top']
            right = obj['right']
            bottom = obj['bottom']

            d.screenshot(sourcePng)  # 截取整个输入验证码时的屏幕

            img = Image.open(sourcePng)
            box = (left, top, right, bottom)  # left top right bottom
            region = img.crop(box)  # 截取验证码的图片

            img = Image.new('RGBA', (right - left, bottom - top))
            img.paste(region, (0, 0))

            img.save(codePng)
            with open(codePng, 'rb') as f:
                # file = f.read()
                file = "data:image/jpeg;base64," + base64.b64encode(f.read())
                da = {"IMAGES": file}
                path = "/ocr.index"
                headers = {
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Connection": "Keep-Alive"
                }
                conn = httplib.HTTPConnection("162626i1w0.51mypc.cn",
                                              10082,
                                              timeout=30)
                params = urllib.urlencode(da)
                conn.request(method="POST",
                             url=path,
                             body=params,
                             headers=headers)
                response = conn.getresponse()
                if response.status == 200:
                    code = response.read()
                else:
                    continue
            os.remove(sourcePng)
            os.remove(codePng)
            z.heartbeat()
            if code.isalpha() or code.isisdigitv() or code.isalnum():
                break
            else:
                continue

        return code

    def login(self, d, z, args, accounts):
        try:
            d.server.adb.cmd(
                "shell",
                "pm clear com.tencent.androidqqmail").communicate()  # 清除QQ邮箱缓存
            d.server.adb.cmd(
                "shell",
                "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail"
            ).communicate()  # 拉起QQ邮箱
            z.sleep(15)
            z.heartbeat()
            Str = d.info  # 获取屏幕大小等信息
            height = int(Str["displayHeight"])
            width = int(Str["displayWidth"])
            for x in range(2):

                if args['mail_type'] == '163邮箱登录':
                    if d(resourceId='com.tencent.androidqqmail:id/ee'
                         ).exists:  # 选择163邮箱点击进入登陆页面
                        d(resourceId='com.tencent.androidqqmail:id/ee').click()
                        z.sleep(1)
                        break
                    else:
                        d.server.adb.cmd(
                            "shell",
                            "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail"
                        ).communicate()  # 拉起QQ邮箱
                        z.sleep(25)
                        continue

                if args['mail_type'] == 'QQ邮箱登录':
                    if d(resourceId='com.tencent.androidqqmail:id/ea'
                         ).exists:  # 选择QQ邮箱点击进入登陆页面
                        d(resourceId='com.tencent.androidqqmail:id/ea').click()
                        z.sleep(1)
                        break
                    else:
                        d.server.adb.cmd(
                            "shell",
                            "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail"
                        ).communicate()  # 拉起QQ邮箱
                        z.sleep(25)
                        continue

                if args['mail_type'] == '腾讯企业邮箱登录':
                    if d(resourceId='com.tencent.androidqqmail:id/eb'
                         ).exists:  # 选择腾讯企业邮箱登录点击进入登陆页面
                        d(resourceId='com.tencent.androidqqmail:id/eb').click()
                        z.sleep(1)
                        break
                    else:
                        d.server.adb.cmd(
                            "shell",
                            "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail"
                        ).communicate()  # 拉起QQ邮箱
                        z.sleep(25)
                        continue

            account = accounts[0]['number']
            password = accounts[0]['password']

            if d(text='帐号密码登录').exists:
                d(text='帐号密码登录').click()

            if d(resourceId='com.tencent.androidqqmail:id/bi'
                 ).exists:  # 输入邮箱帐号
                d(resourceId='com.tencent.androidqqmail:id/bi').click()
                # self.input(z,height,account)
                self.input(z, height, account)
            else:
                return

            if d(resourceId='com.tencent.androidqqmail:id/bs'
                 ).exists:  # 输入邮箱密码
                d(resourceId='com.tencent.androidqqmail:id/bs').click()
                self.input(z, height, password)

            if d(resourceId='com.tencent.androidqqmail:id/a_'
                 ).exists:  # 点击登录按钮
                d(resourceId='com.tencent.androidqqmail:id/a_').click()

            z.sleep(20)
            while True:
                if d(textContains="验证中"):
                    time.sleep(3)
                else:
                    break
            if args['mail_type'] == 'QQ邮箱登录':
                if d(resourceId='com.tencent.androidqqmail:id/h'
                     ).exists:  # 判断是否要填写独立密码
                    self.input(z, height, "Abc" + account)
                    z.sleep(1)
                    if d(text='确定').exists:
                        d(text='确定').click()
                    z.sleep(5)

                while d(resourceId='com.tencent.androidqqmail:id/a16'
                        ).exists:  # 出现验证码
                    picObj = d(resourceId='com.tencent.androidqqmail:id/a19',
                               index=0)
                    code = self.palyCode(d, z, picObj)
                    if code == "":
                        return False
                    if d(resourceId='com.tencent.androidqqmail:id/a17').exists:
                        d(resourceId='com.tencent.androidqqmail:id/a17').click(
                        )
                    self.input(z, height, code)
                    if d(resourceId='com.tencent.androidqqmail:id/a_'
                         ).exists:  # 点击登陆
                        d(resourceId='com.tencent.androidqqmail:id/a_').click()
                    z.sleep(8)

                if d(resourceId='com.tencent.androidqqmail:id/h'
                     ).exists:  # 判断是否要填写独立密码
                    self.input(z, height, "Abc" + account)
                    z.sleep(1)
                    if d(text='确定').exists:
                        d(text='确定').click()

            if args['mail_type'] == '163邮箱登录':
                if d(resourceId='com.tencent.androidqqmail:id/a_'
                     ).exists:  # 点击完成按钮
                    d(resourceId='com.tencent.androidqqmail:id/a_').click()
                    time.sleep(3)
                    d.server.adb.cmd(
                        "shell",
                        "am force-stop com.tencent.androidqqmail").communicate(
                        )  # 强制停止
                    d.server.adb.cmd(
                        "shell",
                        "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail"
                    ).communicate()  # 拉起QQ邮箱
                    # z.sleep(3)
                    # z.heartbeat()

                # d.server.adb.cmd("shell", "am force-stop com.tencent.androidqqmail").wait()  # 强制停止163邮箱
                # d.server.adb.cmd("shell", "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail").communicate()  # 拉起163邮箱

            if args['mail_type'] == '腾讯企业邮箱登录':
                if d(resourceId='com.tencent.androidqqmail:id/a_'
                     ).exists:  # 点击登录按钮
                    d(resourceId='com.tencent.androidqqmail:id/a_').click()
                    z.sleep(3)
                    z.heartbeat()
                    d.server.adb.cmd(
                        "shell",
                        "am force-stop com.tencent.androidqqmail").communicate(
                        )  # 强制停止
                    d.server.adb.cmd(
                        "shell",
                        "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail"
                    ).communicate()  # 拉起QQ邮箱

                if d(text='收件箱​').exists:
                    z.toast(u"登录成功。退出模块")
                    # d.server.adb.cmd( "shell", "am force-stop com.tencent.androidqqmail" ).wait( )  # 强制停止
                    return True
                else:
                    return False
                # d.server.adb.cmd("shell", "am force-stop com.tencent.androidqqmail").wait()  # 强制停止163邮箱
                # d.server.adb.cmd("shell", "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail").communicate()  # 拉起163邮箱

            z.sleep(12)
            z.heartbeat()
            if d(textContains='你有多个应用同时收到').exists:
                d(text='确定').click()
                z.sleep(2)

            if d(text='收件箱​').exists:
                z.toast(u"登录成功。退出模块")
                # d.server.adb.cmd("shell", "am force-stop com.tencent.androidqqmail").wait()  # 强制停止
                return True
            else:
                return False
        except:
            logging.exception("exception")
            z.toast(u"程序出现异常,模块退出")
            d.server.adb.cmd(
                "shell",
                "am force-stop com.tencent.androidqqmail").wait()  # 强制停止
            return False

    def qiehuan(self, d, z, args):
        Str = d.info  # 获取屏幕大小等信息
        height = int(Str["displayHeight"])
        width = int(Str["displayWidth"])
        if args['mail_type'] == '163邮箱登录':
            self.type = '163mail'
        time_limit = int(args['slot_time_limit'])
        serial = d.server.adb.device_serial()
        self.slot = Slot(serial, self.type)
        slotObj = self.slot.getAvailableSlot(time_limit)  # 没有空卡槽,取2小时没用过的卡槽

        slotnum = None
        if not slotObj is None:
            slotnum = slotObj['id']

        while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\""
            ).communicate()
            z.heartbeat()
            z.sleep(30)
            slotObj = self.slot.getAvailableSlot(time_limit)
            if not slotObj is None:
                slotnum = slotObj['id']
                break

        z.heartbeat()
        d.server.adb.cmd(
            "shell",
            "pm clear com.tencent.androidqqmail").communicate()  # 清除缓存

        obj = self.slot.getSlotInfo(slotnum)
        remark = obj['remark']
        remarkArr = remark.split("_")
        cateId = args['repo_account_id']
        if len(remarkArr) == 3:
            slotInfo = d.server.adb.device_serial(
            ) + '_' + self.type + '_' + slotnum
            cateId = remarkArr[2]
            numbers = self.repo.Getserial(cateId, slotInfo)
            if len(numbers) != 0:
                featureCodeInfo = numbers[0]['imei']
                z.set_serial("com.tencent.androidqqmail", featureCodeInfo)

        self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽
        z.sleep(2)

        d.server.adb.cmd(
            "shell",
            "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" +
            slotnum + "号\"").communicate()
        z.sleep(2)
        d.server.adb.cmd(
            "shell",
            "am start -n com.tencent.androidqqmail/com.tencent.qqmail.LaunchComposeMail"
        ).communicate()  # 拉起QQ邮箱
        z.sleep(5)
        while d(textContains='正在更新数据').exists:
            z.sleep(2)
        z.sleep(20)

        z.heartbeat()
        d.dump(compressed=False)
        if d(text='密码错误,请重新输入').exists or d(description='QQ邮箱').exists:
            QQnumber = remarkArr[1]
            self.repo.BackupInfo(cateId, 'normal', QQnumber, '',
                                 '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

            self.slot.clear(slotnum)  # 清空改卡槽,并补登
            z.toast("卡槽邮箱号状态异常,补登陆卡槽")
            return False

        else:
            z.toast("邮箱登陆状态正常,切换完毕。")
            return True

    def action(self, d, z, args):

        while True:
            # z.toast("正在ping网络是否通畅")
            # i = 0
            # while i < 200:
            #     i += 1
            #     ping = d.server.adb.cmd("shell", "ping -c 3 baidu.com").communicate()
            #     # print(ping)
            #     if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
            #         z.toast(u"网络通畅。开始执行:" + args['mail_type'] + u" 有卡槽")
            #         break
            #     z.sleep(2)
            # if i > 200:
            #     z.toast(u"网络不通,请检查网络状态")
            #     return
            Str = d.info  # 获取屏幕大小等信息
            height = int(Str["displayHeight"])
            width = int(Str["displayWidth"])
            z.heartbeat()
            z.generate_serial("com.tencent.androidqqmail")  # 随机生成手机特征码
            d.server.adb.cmd(
                "shell", "su -c 'rm -r -f /storage/emulated/0/tencent/QQmail'"
            )  # 删除/storage/emulated/0/tencent/QQmail文件夹
            time.sleep(2)
            if args['mail_type'] == '163邮箱登录':
                self.type = '163mail'

            accounts = self.repo.GetAccount(args['repo_account_id'],
                                            int(args['account_time_limit']),
                                            1)  # 去仓库获取QQ邮箱帐号
            if len(accounts) == 0:
                z.toast(u"帐号库为空")

            # self.qiehuan( d, z, args )
            serial = d.server.adb.device_serial()
            self.slot = Slot(serial, self.type)
            slotnum = self.slot.getEmpty()  # 取空卡槽
            if slotnum == 0 or len(
                    accounts) == 0:  # 没有空卡槽的话或者仓库没有可登陆的帐号,进行卡槽切换。
                if self.qiehuan(d, z, args):
                    break
                else:
                    continue
            else:  # 有空卡槽的情况

                QQnumber = accounts[0]['number']
                password = accounts[0]['password']
                # print QQnumber
                if self.login(d, z, args, accounts):
                    z.heartbeat()
                    featureCodeInfo = z.get_serial("com.tencent.androidqqmail")
                    self.slot.backup(slotnum,
                                     str(slotnum) + '_' + QQnumber + '_' +
                                     args["repo_account_id"])  # 设备信息,卡槽号,QQ号
                    self.repo.BackupInfo(
                        args["repo_account_id"], 'using', QQnumber,
                        featureCodeInfo,
                        '%s_%s_%s' % (d.server.adb.device_serial(), self.type,
                                      slotnum))  # 仓库号,使用中,QQ号,设备号_卡槽号
                    break

                else:
                    self.slot.clear(slotnum)  # 清空改卡槽,并补登
                    if d(text='本次登录存在异常,如需帮助请前往安全中心').exists:
                        z.toast(u"登录失败。重新登录")
                        self.repo.BackupInfo(args["repo_account_id"], 'frozen',
                                             QQnumber, '',
                                             '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                    elif d(textContains='帐号或密码错误').exists:
                        z.toast(u"帐号或密码错误")
                        againCount = int(args["againCount"])
                        for ac in range(againCount):
                            result = self.againLogin(QQnumber, password, d, z,
                                                     height)
                            if result is True:
                                # z.toast( "跳出模块" )
                                return
                        else:
                            z.toast(u"一直登陆出现密码错误,跳出该帐号")
                        # self.repo.BackupInfo(args["repo_account_id"], 'frozen', QQnumber, '', '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

                    elif d(textContains="未开启IMAP服务").exists:
                        z.toast(u"未开启IMAP服务,标记为异常")
                        self.repo.BackupInfo(args["repo_account_id"],
                                             'exception', QQnumber, '',
                                             '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                    else:
                        self.repo.BackupInfo(args["repo_account_id"], 'normal',
                                             QQnumber, '',
                                             '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
                    continue
예제 #14
0
class MobilqqLogin:
    def __init__(self):
        self.type = 'mobileqq'
        self.repo = Repo()

    def GetUnique(self):
        nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
        # 生成当前时间
        randomNum = random.randint(0, 1000)
        # 生成的随机整数n,其中0<=n<=100
        if randomNum <= 10:
            randomNum = str(00) + str(randomNum)
        uniqueNum = str(nowTime) + str(randomNum)
        return uniqueNum

    def WebViewBlankPages(self, d):
        Str = d.info  # 获取屏幕大小等信息
        height = float(Str["displayHeight"])
        width = float(Str["displayWidth"])

        W_H = width / height
        screenScale = round(W_H, 2)

        base_dir = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir, "tmp"))
        if not os.path.isdir(base_dir):
            os.mkdir(base_dir)
        sourcePng = os.path.join(base_dir, "%s_s.png" % (self.GetUnique()))

        if screenScale == 0.56:
            left = 60  # 验证码的位置信息
            top = 500
            right = 290
            bottom = 600
        if screenScale == 0.61:
            left = 60  # 验证码的位置信息
            top = 490
            right = 210
            bottom = 510

        # left = width * 7 / 135  # 验证码的位置信息
        # top = height * 245 / 444
        # right = width * 51 / 54
        # bottom = height * 275 / 444

        d.screenshot(sourcePng)  # 截取整个输入验证码时的屏幕

        img = Image.open(sourcePng)
        box = (left, top, right, bottom)  # left top right bottom
        region = img.crop(box)  # 截取验证码的图片
        # show(region)    #展示资料卡上的信息
        image = region.convert('RGBA')
        # 生成缩略图,减少计算量,减小cpu压力
        image.thumbnail((200, 200))
        max_score = None
        dominant_color = None
        for count, (r, g, b,
                    a) in image.getcolors(image.size[0] * image.size[1]):
            # 跳过纯黑色
            if a == 0:
                continue
            saturation = colorsys.rgb_to_hsv(r / 255.0, g / 255.0,
                                             b / 255.0)[1]
            y = min(
                abs(r * 2104 + g * 4130 + b * 802 + 4096 + 131072) >> 13, 235)
            y = (y - 16.0) / (235 - 16)
            # 忽略高亮色
            if y > 0.9:
                continue

            score = (saturation + 0.1) * count
            if score > max_score:
                max_score = score
                dominant_color = (r, g, b)  # 红绿蓝
        return dominant_color

    def WebViewPlayCode(self, d, z):
        z.toast("开始截图打码")

        Str = d.info  # 获取屏幕大小等信息
        height = float(Str["displayHeight"])
        width = float(Str["displayWidth"])
        W_H = width / height
        screenScale = round(W_H, 2)

        base_dir = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir, "tmp"))
        if not os.path.isdir(base_dir):
            os.mkdir(base_dir)
        sourcePng = os.path.join(base_dir, "%s_s.png" % (self.GetUnique()))
        icode = imageCode()
        im_id = ""
        for i in range(0, 1):  # 打码循环
            if i > 0:
                icode.reportError(im_id)

            d.screenshot(sourcePng)  # 截取整个输入验证码时的屏幕
            if screenScale == 0.61:
                p = {
                    "x1": 30 / width,
                    "y1": 200 / height,
                    "x2": 271 / width,
                    "y2": 300 / height
                }
            if screenScale == 0.56:
                p = {
                    "x1": 40 / width,
                    "y1": 270 / height,
                    "x2": 362 / width,
                    "y2": 400 / height
                }
            cropedImg = z.img_crop(sourcePng, p)
            im = open(cropedImg, 'rb')
            codeResult = icode.getCode(im, icode.CODE_TYPE_4_NUMBER_CHAR, 60)
            code = codeResult["Result"]
            im_id = codeResult["Id"]
            os.remove(sourcePng)
            z.heartbeat()
            z.sleep(5)
            if screenScale == 0.61:
                d.click(360, 240)
            if screenScale == 0.56:
                d.click(500, 350)
            z.input(code)
            z.sleep(2)
            if screenScale == 0.61:
                d.click(270, 450)
            if screenScale == 0.56:
                d.click(360, 600)

            while d(className='android.widget.ProgressBar',
                    index=0).exists:  # 网速不给力时,点击完成后仍然在加载时的状态
                z.sleep(2)
            z.sleep(8)

            if not d(textContains='验证码').exists:
                z.toast("机器人打码跳出--")
                break

    def BindAddressBook(self, z, d, args):
        z.toast("点击开始绑定")
        self.scode = smsCode(d.server.adb.device_serial())
        d(text='马上绑定').click()
        while d(text='验证手机号码').exists:

            PhoneNumber = None
            j = 0
            while PhoneNumber is None:
                j += 1
                PhoneNumber = self.scode.GetPhoneNumber(
                    self.scode.QQ_CONTACT_BIND)  # 获取接码平台手机号码
                z.heartbeat()
                if j == 2:
                    z.toast('取不到手机号码')
                    if (args["time_delay"]):
                        z.sleep(int(args["time_delay"]))
                    return

            if not d(textContains='+86').exists:
                d(description='点击选择国家和地区').click()
                if d(text='中国').exists:
                    d(text='中国').click()
                else:
                    str = d.info  # 获取屏幕大小等信息
                    height = str["displayHeight"]
                    width = str["displayWidth"]
                    d.click(width * 5 / 12, height * 5 / 32)
                    z.sleep(1.5)
                    z.input('中国')
                    z.sleep(2)
                    d(text='+86').click()

            z.input(PhoneNumber)
            z.sleep(1.5)
            if d(text='下一步').exists:
                d(text='下一步').click()
                z.sleep(3)

            e = 0
            while d(text='正在发送请求').exists:
                z.sleep(2)
            z.sleep(10)
            z.heartbeat()
            if d(text='确定').exists:
                d(text='确定').click()
                z.sleep(2)
            code = self.scode.GetVertifyCode(PhoneNumber,
                                             self.scode.QQ_CONTACT_BIND,
                                             '4')  # 获取接码验证码
            self.scode.defriendPhoneNumber(PhoneNumber,
                                           self.scode.QQ_CONTACT_BIND)
            if code == '':
                z.toast(PhoneNumber + '手机号,获取不到验证码')
                if d(text='返回').exists:
                    d(text='返回').click()
                if not d(textContains='中国').exists:
                    if d(text='返回').exists:
                        d(text='返回').click()
                if d(className='android.view.View',
                     descriptionContains='删除').exists:
                    d(className='android.view.View',
                      descriptionContains='删除').click()
                continue
            z.heartbeat()
            z.input(code)
            if d(text='完成').exists:
                d(text='完成').click()
            z.sleep(15)
            break

    def login(self, d, args, z):
        z.heartbeat()
        self.scode = smsCode(d.server.adb.device_serial())
        base_dir = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir, "tmp"))
        if not os.path.isdir(base_dir):
            os.mkdir(base_dir)
        sourcePng = os.path.join(base_dir, "%s_s.png" % (self.GetUnique()))
        codePng = os.path.join(base_dir, "%s_c.png" % (self.GetUnique()))
        cate_id = args["repo_cate_id"]

        time_limit1 = args['time_limit1']
        numbers = self.repo.GetAccount(cate_id, time_limit1, 1)
        while len(numbers) == 0:
            z.heartbeat()
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"QQ帐号库%s号仓库无%s分钟未用,开始切换卡槽\""
                % (cate_id, time_limit1)).communicate()
            z.sleep(2)
            return 0

        QQNumber = numbers[0]['number']  # 即将登陆的QQ号
        QQPassword = numbers[0]['password']
        z.sleep(1)
        z.heartbeat()
        d.server.adb.cmd("shell",
                         "pm clear com.tencent.mobileqq").communicate()  # 清除缓存
        d.server.adb.cmd(
            "shell",
            "am start -n com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity"
        ).communicate()  # 拉起来
        while d(textContains='正在更新数据').exists:
            z.sleep(2)

        z.sleep(20)
        z.heartbeat()
        d.dump(compressed=False)
        if d(text='登 录',
             resourceId='com.tencent.mobileqq:id/btn_login').exists:
            d(text='登 录').click()

        z.sleep(1)
        # d(className='android.widget.EditText', index=0).set_text(QQNumber)  # 1918697054----xiake1234.  QQNumber
        d(className='android.widget.EditText',
          index=0).click()  # 1918697054----xiake1234.  QQNumber
        z.input(QQNumber)
        z.sleep(1)
        # d(resourceId='com.tencent.mobileqq:id/password').set_text(QQPassword)  # Bn2kJq5l     QQPassword
        d(resourceId='com.tencent.mobileqq:id/password').click(
        )  # Bn2kJq5l     QQPassword
        z.input(QQPassword)
        z.heartbeat()
        logger = util.logger
        print('QQ号:%s,QQ密码:%s' % (QQNumber, QQPassword))
        d.dump(compressed=False)
        d(text='登 录', resourceId='com.tencent.mobileqq:id/login').click()
        z.sleep(1)
        while d(text='登录中').exists:
            z.sleep(2)
        z.sleep(20)
        z.heartbeat()

        loginStatusList = z.qq_getLoginStatus(d)
        if loginStatusList is None:
            if d(text='消息').exists and d(text='联系人').exists and d(
                    text='动态').exists:
                loginStatusList = {'success': True}
            else:
                loginStatusList = {'success': False}

        loginStatus = loginStatusList['success']
        if loginStatus:
            return QQNumber

        detection_robot = d(index='3', className="android.widget.EditText")
        not_detection_robot = d(resourceId='com.tencent.mobileqq:id/name',
                                index='2',
                                className="android.widget.EditText")
        if detection_robot.exists or not_detection_robot.exists:  # 需要验证码的情况
            z.toast("非网页打码")
            icode = imageCode()
            im_id = ""
            for i in range(0, 4):  # 打码循环
                if i > 0:
                    icode.reportError(im_id)
                obj = d(resourceId='com.tencent.mobileqq:id/name',
                        className='android.widget.ImageView'
                        )  # 当弹出选择QQ框的时候,定位不到验证码图片
                if not obj.exists:
                    obj = d(index='2', className='android.widget.Image')
                obj = obj.info
                obj = obj['bounds']  # 验证码处的信息
                left = obj["left"]  # 验证码的位置信息
                top = obj['top']
                right = obj['right']
                bottom = obj['bottom']

                d.screenshot(sourcePng)  # 截取整个输入验证码时的屏幕

                img = Image.open(sourcePng)
                box = (left, top, right, bottom)  # left top right bottom
                region = img.crop(box)  # 截取验证码的图片

                img = Image.new('RGBA', (right - left, bottom - top))
                img.paste(region, (0, 0))

                img.save(codePng)
                im = open(codePng, 'rb')

                codeResult = icode.getCode(im, icode.CODE_TYPE_4_NUMBER_CHAR,
                                           60)

                code = codeResult["Result"]
                im_id = codeResult["Id"]
                os.remove(sourcePng)
                os.remove(codePng)
                z.heartbeat()
                z.sleep(5)
                if not_detection_robot.exists:
                    d(resourceId='com.tencent.mobileqq:id/name',
                      index='2',
                      className="android.widget.EditText").set_text(code)
                else:
                    detection_robot.set_text(code)
                z.sleep(3)
                if d(descriptionContains='验证',
                     className='android.view.View').exists:
                    d(descriptionContains='验证',
                      className='android.view.View').click()
                else:
                    d(text='完成',
                      resourceId='com.tencent.mobileqq:id/ivTitleBtnRightText'
                      ).click()
                z.sleep(6)
                z.heartbeat()
                while d(className='android.widget.ProgressBar',
                        index=0).exists:  # 网速不给力时,点击完成后仍然在加载时的状态
                    z.sleep(2)
                z.sleep(3)
                z.heartbeat()
                if detection_robot.exists or not_detection_robot.exists:
                    continue
                else:
                    break
            z.sleep(5)
            if d(textContains='验证码').exists:
                return "nothing"
        else:
            if self.WebViewBlankPages(d)[2] > 200:
                z.toast("不是空白页")
                self.WebViewPlayCode(d, z)

        z.heartbeat()
        # z.toast( "强制停止,拉起" )
        # d.server.adb.cmd( "shell", "am force-stop com.tencent.mobileqq" ).communicate( )  # 强制停止
        # z.sleep( 1 )
        # d.server.adb.cmd( "shell",
        #                   "am start -n com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity" ).communicate( )  # 拉起来

        z.sleep(5)
        z.heartbeat()
        loginStatusList = z.qq_getLoginStatus(d)
        if loginStatusList is None:
            if d(text='消息').exists and d(text='联系人').exists and d(
                    text='动态').exists:
                loginStatusList = {'success': True}
            else:
                z.toast("登陆新场景,现无法判断登陆状态")
                loginStatusList = {'success': False}

        loginStatus = loginStatusList['success']
        if loginStatus:
            z.toast("卡槽QQ状态正常,继续执行")
        else:
            if d(text='去安全中心').exists:
                self.repo.BackupInfo(cate_id, 'frozen', QQNumber, '',
                                     '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

            else:
                self.repo.BackupInfo(cate_id, 'normal', QQNumber, '', '')

            z.toast("卡槽QQ状态异常,跳过此模块")
            return "nothing"

        if d(text='马上绑定').exists:
            self.BindAddressBook(z, d, args)

        if d(text='匹配手机通讯录').exists:  # 登陆上后弹出t通讯录的情况
            d(text='匹配手机通讯录').click()
            z.sleep(1.5)
            if d(text='取消').exists:
                d(text='取消').child()

        if d(textContains="请在小米神隐模式中将TIM设置为“无限制”。").exists:
            z.toast("我是小米神隐")
            d(text='我知道了').click()

        return QQNumber

    def qiehuan(self, d, z, args):
        time_limit = int(args['time_limit'])
        cate_id = args["repo_cate_id"]
        serial = d.server.adb.device_serial()
        self.slot = Slot(serial, self.type)
        slotObj = self.slot.getAvailableSlot(time_limit)  # 没有空卡槽,取2小时没用过的卡槽
        if not slotObj is None:
            slotnum = slotObj['id']
        while slotnum == 0:  # 2小时没有用过的卡槽也为空的情况
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\""
            ).communicate()
            z.heartbeat()
            z.sleep(30)
            slotObj = self.slot.getAvailableSlot(
                time_limit)  # 没有空卡槽,取2小时没用过的卡槽
            if not slotObj is None:
                slotnum = slotObj['id']
        z.heartbeat()
        d.server.adb.cmd("shell",
                         "pm clear com.tencent.mobileqq").communicate()  # 清除缓存

        d.server.adb.cmd(
            "shell", "settings put global airplane_mode_on 1").communicate()
        d.server.adb.cmd(
            "shell",
            "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true"
        ).communicate()
        z.sleep(6)
        z.heartbeat()
        d.server.adb.cmd(
            "shell", "settings put global airplane_mode_on 0").communicate()
        d.server.adb.cmd(
            "shell",
            "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false"
        ).communicate()
        z.heartbeat()
        while True:
            ping = d.server.adb.cmd("shell",
                                    "ping -c 3 baidu.com").communicate()
            print(ping)
            if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                break
            z.sleep(2)

        obj = self.slot.getSlotInfo(slotnum)
        remark = obj['remark']
        remarkArr = remark.split("_")
        if len(remarkArr) == 3:
            slotInfo = d.server.adb.device_serial(
            ) + '_' + self.type + '_' + slotnum
            cateId = remarkArr[2]
            numbers = self.repo.Getserial(cateId, slotInfo)
            featureCodeInfo = numbers[0]['imei']
            z.set_serial("com.tencent.mobileqq", featureCodeInfo)

        self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽

        d.server.adb.cmd(
            "shell",
            "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" +
            str(slotnum) + "号\"").communicate()
        z.sleep(2)
        if d(textContains='主题装扮').exists:
            d(text='关闭').click()
            z.sleep(1)

        d.server.adb.cmd(
            "shell",
            "am start -n com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity"
        ).communicate()  # 拉起来
        z.sleep(2)
        z.heartbeat()

        loginStatusList = z.qq_getLoginStatus(d)
        if loginStatusList is None:
            if d(text='消息').exists and d(text='联系人').exists and d(
                    text='动态').exists:
                loginStatusList = {'success': True}
            else:
                z.toast("登陆新场景,现无法判断登陆状态")
                loginStatusList = {'success': False}

        loginStatus = loginStatusList['success']
        if loginStatus:
            z.toast("卡槽QQ状态正常,继续执行")
        else:
            obj = self.slot.getSlotInfo(slotnum)
            remark = obj['remark']
            remarkArr = remark.split("_")
            QQnumber = remarkArr[1]
            if d(text='去安全中心').exists:
                self.repo.BackupInfo(cate_id, 'frozen', QQnumber, '',
                                     '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

            else:
                self.repo.BackupInfo(cate_id, 'normal', QQnumber, '', '')

            self.slot.clear(slotnum)  # 清空改卡槽,并补登
            z.toast("卡槽QQ状态异常,补登陆卡槽")
            self.action(d, z, args)

        if d(text='马上绑定').exists:
            self.BindAddressBook(z, d, args)

        if d(textContains="请在小米神隐模式中将TIM设置为“无限制”。").exists:
            z.toast("我是小米神隐")
            d(text='我知道了').click()

        if d(text='匹配手机通讯录').exists:  # 登陆上后弹出t通讯录的情况
            d(text='匹配手机通讯录').click()
            z.sleep(1.5)
            if d(text='取消').exists:
                d(text='取消').child()

    def action(self, d, z, args):
        z.toast("正在ping网络是否通畅")
        z.heartbeat()
        i = 0
        while i < 200:
            i += 1
            ping = d.server.adb.cmd("shell",
                                    "ping -c 3 baidu.com").communicate()
            print(ping)
            if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                z.toast("网络通畅。开始执行:普通QQ登录有卡槽")
                break
            z.sleep(2)
        if i > 200:
            z.toast("网络不通,请检查网络状态")
            if (args["time_delay"]):
                z.sleep(int(args["time_delay"]))
            return

        z.heartbeat()
        z.generate_serial("com.tencent.mobileqq")  # 随机生成手机特征码

        time_limit = int(args['time_limit'])
        cate_id = args["repo_cate_id"]
        serial = d.server.adb.device_serial()
        self.slot = Slot(serial, self.type)
        slotnum = self.slot.getEmpty()  # 取空卡槽
        if slotnum == 0:  #没有空卡槽的话
            slotObj = self.slot.getAvailableSlot(time_limit)  # 取空卡槽,取2小时没用过的卡槽
            if not slotObj is None:
                slotnum = slotObj['id']
            print(slotnum)
            while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
                d.server.adb.cmd(
                    "shell",
                    "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\""
                ).communicate()
                z.heartbeat()
                z.sleep(30)
                slotObj = self.slot.getAvailableSlot(time_limit)
                if not slotObj is None:
                    slotnum = slotObj['id']
            z.heartbeat()
            d.server.adb.cmd(
                "shell", "pm clear com.tencent.mobileqq").communicate()  # 清除缓存

            d.server.adb.cmd(
                "shell",
                "settings put global airplane_mode_on 1").communicate()  #开飞行模式
            d.server.adb.cmd(
                "shell",
                "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true"
            ).communicate()
            z.sleep(6)
            z.heartbeat()

            d.server.adb.cmd("shell", "settings put global airplane_mode_on 0"
                             ).communicate()  # 关飞行模式
            d.server.adb.cmd(
                "shell",
                "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false"
            ).communicate()

            z.heartbeat()
            while True:
                ping = d.server.adb.cmd("shell",
                                        "ping -c 3 baidu.com").communicate()
                print(ping)
                if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                    break
                z.sleep(2)

            obj = self.slot.getSlotInfo(slotnum)
            remark = obj['remark']
            remarkArr = remark.split("_")
            if len(remarkArr) == 3:
                slotInfo = d.server.adb.device_serial(
                ) + '_' + self.type + '_' + slotnum
                cateId = remarkArr[2]
                numbers = self.repo.Getserial(cateId, slotInfo)
                featureCodeInfo = numbers[0]['imei']
                z.set_serial("com.tencent.mobileqq", featureCodeInfo)

            self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽
            z.sleep(2)
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" +
                slotnum + "号\"").communicate()
            z.sleep(2)

            d.server.adb.cmd(
                "shell",
                "am start -n com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity"
            ).communicate()  # 拉起来

            z.sleep(2)
            z.heartbeat()

            loginStatusList = z.qq_getLoginStatus(d)
            if loginStatusList is None:
                if d(text='消息').exists and d(text='联系人').exists and d(
                        text='动态').exists:
                    loginStatusList = {'success': True}
                else:
                    z.toast("登陆新场景,现无法判断登陆状态")
                    loginStatusList = {'success': False}

            loginStatus = loginStatusList['success']
            if loginStatus:
                z.toast("卡槽QQ状态正常,继续执行")
            else:
                obj = self.slot.getSlotInfo(slotnum)
                remark = obj['remark']
                remarkArr = remark.split("_")
                QQnumber = remarkArr[1]
                if d(text='去安全中心').exists:
                    self.repo.BackupInfo(cate_id, 'frozen', QQnumber, '',
                                         '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

                else:
                    self.repo.BackupInfo(cate_id, 'normal', QQnumber, '', '')

                self.slot.clear(slotnum)  # 清空改卡槽,并补登
                z.toast("卡槽QQ状态异常,补登陆卡槽")
                self.action(d, z, args)

            if d(text='马上绑定').exists:
                self.BindAddressBook(z, d, args)

            if d(textContains="请在小米神隐模式中将TIM设置为“无限制”。").exists:
                z.toast("我是小米神隐")
                d(text='我知道了').click()

            if d(text='匹配手机通讯录').exists:  # 登陆上后弹出t通讯录的情况
                d(text='匹配手机通讯录').click()
                z.sleep(1.5)
                if d(text='取消').exists:
                    d(text='取消').child()

        else:  # 有空卡槽的情况
            d.server.adb.cmd(
                "shell", "pm clear com.tencent.mobileqq").communicate()  # 清除缓存

            d.server.adb.cmd(
                "shell",
                "settings put global airplane_mode_on 1").communicate()
            d.server.adb.cmd(
                "shell",
                "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true"
            ).communicate()
            z.sleep(6)
            d.server.adb.cmd(
                "shell",
                "settings put global airplane_mode_on 0").communicate()
            d.server.adb.cmd(
                "shell",
                "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false"
            ).communicate()
            z.heartbeat()
            while True:
                ping = d.server.adb.cmd("shell",
                                        "ping -c 3 baidu.com").communicate()
                print(ping)
                if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                    break
                z.sleep(2)
            serialinfo = d.server.adb.device_serial()
            # print('登陆时的serial%s'%serialinfo)
            z.heartbeat()
            QQnumber = self.login(d, args, z)
            if QQnumber == 'nothing':
                self.slot.clear(slotnum)  # 清空改卡槽,并补登
                self.action(d, z, args)
            if QQnumber == 0:
                z.toast("仓库为空,无法登陆。开始切换卡槽")
                self.qiehuan(d, z, args)
            z.heartbeat()

            featureCodeInfo = z.get_serial("com.tencent.mobileqq")
            self.slot.backup(slotnum,
                             str(slotnum) + '_' + QQnumber + '_' +
                             cate_id)  # 设备信息,卡槽号,QQ号
            self.repo.BackupInfo(cate_id, 'using', QQnumber, featureCodeInfo,
                                 '%s_%s_%s' %
                                 (d.server.adb.device_serial(), self.type,
                                  slotnum))  # 仓库号,使用中,QQ号,设备号_卡槽号

        if (args["time_delay"]):
            z.sleep(int(args["time_delay"]))
예제 #15
0
class TIMLogin03:
    def __init__(self):
        self.repo = Repo()
        self.type = 'tim'

    def IPCheckRepitition(self, z, d, args):
        z.toast("正在检测IP...")
        while True:
            # 开关飞行模式
            d.server.adb.cmd(
                "shell",
                "settings put global airplane_mode_on 1").communicate()
            d.server.adb.cmd(
                "shell",
                "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true"
            ).communicate()
            z.sleep(3)
            d.server.adb.cmd(
                "shell",
                "settings put global airplane_mode_on 0").communicate()
            d.server.adb.cmd(
                "shell",
                "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false"
            ).communicate()

            t = 0
            while t < 6:
                ping = d.server.adb.cmd("shell",
                                        "ping -c 3 baidu.com").communicate()
                print(ping)
                if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                    break
                z.sleep(10)
                z.heartbeat()
                z.sleep(10)
                t = t + 1
            if t >= 6:
                z.toast("网络无法ping通,重新开关飞行模式")
                continue

            # 获取手机IP
            IPList = d.server.adb.cmd(
                "shell", "curl http://ipecho.net/plain").communicate()
            IP = IPList[0]
            print(IP)

            # IP添加到缓存
            ip = cache.get(IP)
            print(ip)
            if ip is None:
                timeoutStr = args['time_out']
                timeout = int(timeoutStr) * 60
                cache.set(IP, IP, timeout)
                z.toast("IP检测完成")
                break
            else:
                continue

    def GetUnique(self):
        nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
        # 生成当前时间
        randomNum = random.randint(0, 1000)
        # 生成的随机整数n,其中0<=n<=100
        if randomNum <= 10:
            randomNum = str(00) + str(randomNum)
        uniqueNum = str(nowTime) + str(randomNum)
        return uniqueNum

    def LoginPlayCode(self, d, z):
        self.scode = smsCode(d.server.adb.device_serial())
        base_dir = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir, "tmp"))
        if not os.path.isdir(base_dir):
            os.mkdir(base_dir)
        sourcePng = os.path.join(base_dir, "%s_s.png" % (self.GetUnique()))
        codePng = os.path.join(base_dir, "%s_c.png" % (self.GetUnique()))
        detection_robot = d(index='3', className="android.widget.EditText")
        not_detection_robot = d(resourceId='com.tencent.tim:id/name',
                                index='2',
                                className="android.widget.EditText")
        if detection_robot.exists or not_detection_robot.exists:  # 需要验证码的情况
            icode = imageCode()
            im_id = ""
            for i in range(0, 4):  # 打码循环
                if i > 0:
                    icode.reportError(im_id)
                obj = d(resourceId='com.tencent.tim:id/name',
                        className='android.widget.ImageView'
                        )  # 当弹出选择QQ框的时候,定位不到验证码图片
                if not obj.exists:
                    obj = d(index='2', className='android.widget.Image')
                obj = obj.info
                obj = obj['bounds']  # 验证码处的信息
                left = obj["left"]  # 验证码的位置信息
                top = obj['top']
                right = obj['right']
                bottom = obj['bottom']

                d.screenshot(sourcePng)  # 截取整个输入验证码时的屏幕

                img = Image.open(sourcePng)
                box = (left, top, right, bottom)  # left top right bottom
                region = img.crop(box)  # 截取验证码的图片

                img = Image.new('RGBA', (right - left, bottom - top))
                img.paste(region, (0, 0))

                img.save(codePng)
                im = open(codePng, 'rb')

                codeResult = icode.getCode(im, icode.CODE_TYPE_4_NUMBER_CHAR,
                                           60)

                code = codeResult["Result"]
                im_id = codeResult["Id"]
                os.remove(sourcePng)
                os.remove(codePng)
                z.heartbeat()
                z.sleep(5)
                if not_detection_robot.exists:
                    d(resourceId='com.tencent.tim:id/name',
                      index='2',
                      className="android.widget.EditText").set_text(code)
                else:
                    detection_robot.set_text(code)
                z.sleep(3)
                if d(descriptionContains='验证',
                     className='android.view.View').exists:
                    d(descriptionContains='验证',
                      className='android.view.View').click()
                else:
                    d(text='完成',
                      resourceId='com.tencent.tim:id/ivTitleBtnRightText'
                      ).click()
                z.sleep(5)
                z.heartbeat()
                while d(className='android.widget.ProgressBar',
                        index=0).exists:  # 网速不给力时,点击完成后仍然在加载时的状态
                    z.sleep(2)
                z.heartbeat()
                if detection_robot.exists or not_detection_robot.exists:
                    continue
                else:
                    break
            z.sleep(5)
            if d(textContains='验证码').exists:
                return "no"
            else:
                return "yes"
        else:
            return "no"

    def login(self, d, args, z):
        z.heartbeat()
        Str = d.info  # 获取屏幕大小等信息
        height = float(Str["displayHeight"])
        width = float(Str["displayWidth"])
        W_H = width / height
        screenScale = round(W_H, 2)

        cate_id = args["repo_cate_id"]
        time_limit1 = args['time_limit1']
        numbers = self.repo.GetAccount(cate_id, time_limit1, 1)
        while len(numbers) == 0:
            z.heartbeat()
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"QQ帐号库%s号仓库无%s分钟未用,开始切换卡槽\""
                % (cate_id, time_limit1)).communicate()
            z.sleep(2)
            return 0

        QQNumber = numbers[0]['number']  # 即将登陆的QQ号
        QQPassword = numbers[0]['password']
        z.sleep(1)
        z.heartbeat()
        d.server.adb.cmd("shell",
                         "pm clear com.tencent.tim").communicate()  # 清除缓存
        # d.server.adb.cmd("shell",
        #                   "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity" ).communicate( )  # 拉起来
        z.server.adb.run_cmd(
            "shell",
            "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity"
        )
        z.sleep(5)
        while d(textContains='正在更新数据').exists:
            z.sleep(2)
        z.sleep(3)
        z.server.adb.run_cmd(
            "shell",
            "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity"
        )
        z.heartbeat()
        if d(className='android.widget.ImageView',
             resourceId='com.tencent.tim:id/title',
             index=1).exists:
            for i in range(0, 2):
                d.swipe(width - 20, height / 2, 0, height / 2, 5)
                z.sleep(1.5)
            if d(text='立即体验').exists:
                d(text='立即体验').click()
        z.sleep(2)
        d.dump(compressed=False)
        if d(text='登 录', resourceId='com.tencent.tim:id/btn_login').exists:
            z.toast("控件点击")
            d(text='登 录').click()
        else:
            d(text='QQ号登录').click()
        z.sleep(1)
        # d(className='android.widget.EditText', index=0).set_text(QQNumber)  # 1918697054----xiake1234.  QQNumber
        d(className='android.widget.EditText',
          index=0).click()  # 1918697054----xiake1234.  QQNumber
        z.input(QQNumber)

        z.sleep(1)
        # d(resourceId='com.tencent.mobileqq:id/password').set_text(QQPassword)  # Bn2kJq5l     QQPassword
        d(resourceId='com.tencent.tim:id/password').click(
        )  # Bn2kJq5l     QQPassword
        z.input(QQPassword)
        z.heartbeat()
        logger = util.logger
        print('QQ号:%s,QQ密码:%s' % (QQNumber, QQPassword))
        d.dump(compressed=False)
        d(text='登 录', resourceId='com.tencent.tim:id/login').click()
        z.sleep(1)
        while d(text='登录中').exists:
            z.sleep(2)
        z.sleep(5)
        z.heartbeat()

        detection_robot = d(index='3', className="android.widget.EditText")
        not_detection_robot = d(resourceId='com.tencent.tim:id/name',
                                index='2',
                                className="android.widget.EditText")
        if detection_robot.exists or not_detection_robot.exists:
            playCodeResult = self.LoginPlayCode(d, z)  # 打验证码

        if playCodeResult == "no":
            return "nothing"

        z.sleep(5)
        z.heartbeat()
        if d(text='马上绑定').exists:
            return QQNumber

        if d(text='匹配手机通讯录').exists:  # 登陆上后弹出t通讯录的情况
            d(text='匹配手机通讯录').click()
            z.sleep(1.5)
            if d(text='取消').exists:
                d(text='取消').child()
            return QQNumber

        if d(text='消息').exists and d(description='快捷入口').exists:
            z.toast("卡槽QQ状态正常,继续执行")
            return QQNumber

        if d(text='去安全中心').exists:
            self.repo.BackupInfo(cate_id, 'frozen', QQNumber, '',
                                 '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
            z.toast("登陆失败,重新登陆")
            return "nothing"
        else:
            self.repo.BackupInfo(cate_id, 'normal', QQNumber, '',
                                 '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
            z.toast("登陆失败,重新登陆")
            return "nothing"

    def qiehuan(self, d, z, args):
        Str = d.info  # 获取屏幕大小等信息
        height = float(Str["displayHeight"])
        width = float(Str["displayWidth"])
        time_limit = int(args['time_limit'])
        cate_id = args["repo_cate_id"]
        serial = d.server.adb.device_serial()
        self.slot = Slot(serial, self.type)
        slotObj = self.slot.getAvailableSlot(time_limit)  # 没有空卡槽,取2小时没用过的卡槽
        while slotObj is None:  # 2小时没有用过的卡槽也为空的情况
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\""
            ).communicate()
            z.heartbeat()
            z.sleep(10)
            slotObj = self.slot.getAvailableSlot(
                time_limit)  # 没有空卡槽,取2小时没用过的卡槽

        if not slotObj is None:
            slotnum = slotObj['id']
        z.heartbeat()
        d.server.adb.cmd("shell",
                         "pm clear com.tencent.tim").communicate()  # 清除缓存

        # d.server.adb.cmd("shell", "settings put global airplane_mode_on 1").communicate()
        # d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true").communicate()
        # z.sleep(6)
        # z.heartbeat()
        # d.server.adb.cmd("shell", "settings put global airplane_mode_on 0").communicate()
        # d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false").communicate()
        # z.heartbeat()
        # z.toast( "正在ping网络是否通畅" )
        # while True:
        #     ping = d.server.adb.cmd("shell", "ping -c 3 baidu.com").communicate()
        #     print(ping)
        #     if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
        #         break
        #     z.sleep(2)

        try:
            self.IPCheckRepitition(z, d, args)
        except:
            z.toast("IP检测出错了,请查找问题")

        self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽

        d.server.adb.cmd(
            "shell",
            "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" +
            str(slotnum) + "号\"").communicate()
        z.sleep(2)
        # d.server.adb.cmd("shell", "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity").communicate()  # 拉起来
        z.server.adb.run_cmd(
            "shell",
            "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity"
        )

        z.sleep(5)
        while d(textContains='正在更新数据').exists:
            z.sleep(2)

        z.sleep(3)
        z.server.adb.run_cmd(
            "shell",
            "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity"
        )
        z.heartbeat()
        if d(className='android.widget.ImageView',
             resourceId='com.tencent.tim:id/title',
             index=1).exists:
            for i in range(0, 2):
                d.swipe(width - 20, height / 2, 0, height / 2, 5)
                z.sleep(1.5)
            if d(text='立即体验').exists:
                d(text='立即体验').click()
        z.sleep(2)

        if d(text='消息').exists or d(text='马上绑定').exists or d(
                text='匹配手机通讯录').exists:
            if d(text='匹配手机通讯录').exists:  # 登陆上后弹出t通讯录的情况
                d(text='匹配手机通讯录').click()
                z.sleep(1.5)
                if d(text='取消').exists:
                    d(text='取消').child()
            z.toast("卡槽QQ切换成功,继续执行")
        else:
            obj = self.slot.getSlotInfo(slotnum)
            remark = obj['remark']
            remarkArr = remark.split("_")
            QQnumber = remarkArr[1]
            if d(text='去安全中心').exists:
                self.repo.BackupInfo(cate_id, 'frozen', QQnumber, '',
                                     '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

            else:
                self.repo.BackupInfo(cate_id, 'normal', QQnumber, '', '')
            self.slot.clear(slotnum)  # 清空改卡槽,并补登
            z.toast("卡槽QQ状态异常,补登陆卡槽")
            self.action(d, z, args)

    def action(self, d, z, args):
        Str = d.info  # 获取屏幕大小等信息
        height = float(Str["displayHeight"])
        width = float(Str["displayWidth"])

        z.generate_serial("com.tencent.tim")  # 随机生成手机特征码
        z.toast("随机生成手机特征码")

        time_limit = int(args['time_limit'])
        cate_id = args["repo_cate_id"]
        serial = d.server.adb.device_serial()
        self.slot = Slot(serial, self.type)
        slotnum = self.slot.getEmpty()  # 取空卡槽
        if slotnum == 0:  # 没有空卡槽的话
            slotObj = self.slot.getAvailableSlot(time_limit)  # 取空卡槽,取2小时没用过的卡槽
            if not slotObj is None:
                slotnum = slotObj['id']
            print(slotnum)
            while slotObj is None:  # 2小时没用过的卡槽也为没有的情况
                d.server.adb.cmd(
                    "shell",
                    "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\""
                ).communicate()
                z.heartbeat()
                z.sleep(10)
                slotObj = self.slot.getAvailableSlot(time_limit)
                if not slotObj is None:
                    slotnum = slotObj['id']
            z.heartbeat()
            # d.server.adb.cmd( "shell", "pm clear com.tencent.tim" ).communicate( )  # 清除缓存
            # d.server.adb.cmd( "shell", "am force-stop com.tencent.tim" ).communicate( )  # 强制停止

            # d.server.adb.cmd("shell", "settings put global airplane_mode_on 1").communicate() #开数据流量
            # d.server.adb.cmd("shell","am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true").communicate()#开飞行模式
            # z.sleep( 6 )
            # z.heartbeat( )
            # d.server.adb.cmd("shell", "settings put global airplane_mode_on 0").communicate() # 关数据流量
            # d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false").communicate()#开飞行模式
            #
            # z.heartbeat( )
            # z.toast( "正在ping网络是否通畅" )
            # while True:
            #     ping = d.server.adb.cmd( "shell", "ping -c 3 baidu.com" ).communicate( )
            #     print( ping )
            #     if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
            #         break
            #     z.sleep( 2 )

            try:
                self.IPCheckRepitition(z, d, args)
            except:
                z.toast("IP检测出错了,请查找问题")

            self.slot.restore(slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽

            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" +
                slotnum + "号\"").communicate()
            z.sleep(2)
            # d.server.adb.cmd( "shell",
            #                   "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity" ).communicate( )  # 拉起来
            z.server.adb.run_cmd(
                "shell",
                "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity"
            )

            z.sleep(5)
            while d(textContains='正在更新数据').exists:
                z.sleep(2)
            z.sleep(3)
            z.server.adb.run_cmd(
                "shell",
                "am start -n com.tencent.tim/com.tencent.mobileqq.activity.SplashActivity"
            )

            if d(className='android.widget.ImageView',
                 resourceId='com.tencent.tim:id/title',
                 index=1).exists:
                for i in range(0, 2):
                    d.swipe(width - 20, height / 2, 0, height / 2, 5)
                    z.sleep(1.5)
                if d(text='立即体验').exists:
                    d(text='立即体验').click()
            z.sleep(2)
            z.heartbeat()
            if d(text='消息').exists or d(text='马上绑定').exists or d(
                    text='匹配手机通讯录').exists:
                if d(text='匹配手机通讯录').exists:  # 登陆上后弹出t通讯录的情况
                    d(text='匹配手机通讯录').click()
                    z.sleep(1.5)
                    if d(text='取消').exists:
                        d(text='取消').click()
                z.toast("卡槽QQ切换成功,继续执行")
            else:
                obj = self.slot.getSlotInfo(slotnum)
                remark = obj['remark']
                remarkArr = remark.split("_")
                QQnumber = remarkArr[1]
                if d(text='去安全中心').exists:
                    self.repo.BackupInfo(cate_id, 'frozen', QQnumber, '',
                                         '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber

                else:
                    self.repo.BackupInfo(cate_id, 'normal', QQnumber, '', '')
                self.slot.clear(slotnum)  # 清空改卡槽,并补登
                z.toast("卡槽QQ状态异常,补登陆卡槽")
                self.action(d, z, args)

        else:  # 有空卡槽的情况
            d.server.adb.cmd("shell",
                             "pm clear com.tencent.tim").communicate()  # 清除缓存

            # d.server.adb.cmd("shell", "settings put global airplane_mode_on 1").communicate()
            # d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true").communicate()
            # z.sleep(3)
            # d.server.adb.cmd("shell", "settings put global airplane_mode_on 0").communicate()
            # d.server.adb.cmd("shell", "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false").communicate()
            # z.heartbeat( )
            # z.toast( "正在ping网络是否通畅" )
            # while True:
            #     ping = d.server.adb.cmd( "shell", "ping -c 3 baidu.com" ).communicate( )
            #     print( ping )
            #     if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
            #         break
            #     z.sleep( 2 )

            try:
                self.IPCheckRepitition(z, d, args)
            except:
                logging.exception("exception")
                z.toast("IP检测出错了,请查找问题")

            serialinfo = d.server.adb.device_serial()
            # print('登陆时的serial%s'%serialinfo)
            z.heartbeat()
            QQnumber = self.login(d, args, z)
            if QQnumber == 'nothing':
                self.slot.clear(slotnum)  # 清空改卡槽,并补登
                self.action(d, z, args)
            elif QQnumber == 0:
                z.toast("仓库为空,无法登陆。开始切换卡槽")
                self.qiehuan(d, z, args)
            elif QQnumber is None:
                return
            else:
                z.heartbeat()
                self.slot.backup(slotnum,
                                 str(slotnum) + '_' + QQnumber)  # 设备信息,卡槽号,QQ号
                self.repo.BackupInfo(cate_id, 'using', QQnumber, serialinfo,
                                     '%s_%s_%s' %
                                     (d.server.adb.device_serial(), self.type,
                                      slotnum))  # 仓库号,使用中,QQ号,设备号_卡槽号

        if (args["time_delay"]):
            time.sleep(int(args["time_delay"]))
예제 #16
0
class MobilqqLogin2:
    def __init__(self):
        self.type = 'mobileqq'
        self.repo = Repo()
        self.slot = Slot('', self.type)
        self.logger = util.logger

    def GetUnique(self):
        nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
        # 生成当前时间
        randomNum = random.randint(0, 1000)
        # 生成的随机整数n,其中0<=n<=100
        if randomNum <= 10:
            randomNum = str(00) + str(randomNum)
        uniqueNum = str(nowTime) + str(randomNum)
        return uniqueNum

    def login(self, d, args, z):
        z.heartbeat()
        base_dir = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir, "tmp"))
        if not os.path.isdir(base_dir):
            os.mkdir(base_dir)
        sourcePng = os.path.join(base_dir, "%s_s.png" % (self.GetUnique()))
        codePng = os.path.join(base_dir, "%s_c.png" % (self.GetUnique()))
        cate_id = args["repo_cate_id"]

        while True:
            time_limit1 = args['time_limit1']
            numbers = self.repo.GetAccount(cate_id, time_limit1, 1)
            t = 30
            while len(numbers) == 0:
                z.heartbeat()

                z.toast('QQ帐号库%s号仓库无%s分钟未用,即将跳出 %s' %
                        (cate_id, time_limit1, t))
                numbers = self.repo.GetAccount(cate_id, time_limit1, 1)
                z.sleep(2)
                t = t - 2
                if t <= 0:
                    return None

            QQNumber = numbers[0]['number']  # 即将登陆的QQ号
            QQPassword = numbers[0]['password']
            z.sleep(1)
            z.heartbeat()
            z.cmd("shell", "pm clear com.tencent.mobileqq")  # 清除缓存
            z.cmd(
                "shell",
                "am start -n com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity"
            )  # 拉起来
            while d(textContains='正在更新数据').exists:
                z.sleep(3)

            z.heartbeat()
            t = 15
            z.toast("等待 登录 按钮出现")
            while not d(resourceId='com.tencent.mobileqq:id/btn_login').exists:
                z.toast("等待 登录 按钮出现 %s" % t)
                dumpStr = d.dump(compressed=False)
                z.sleep(2)
                if t == 9:
                    self.logger.war(dumpStr)
                t = t - 2
            d(resourceId='com.tencent.mobileqq:id/btn_login').click()

            z.sleep(1)
            d(className='android.widget.EditText', index=0).click()
            d(className='android.widget.EditText', index=0).set_text(
                QQNumber)  # 1918697054----xiake1234.  QQNumber
            z.sleep(1)
            d(resourceId='com.tencent.mobileqq:id/password').set_text(
                QQPassword)  # Bn2kJq5l     QQPassword
            z.heartbeat()
            print('QQ号:%s,QQ密码:%s' % (QQNumber, QQPassword))
            d(resourceId='com.tencent.mobileqq:id/login').click()
            if d(text='QQ').exists:
                d(text='QQ').click()
                if d(text='仅此一次').exists:
                    d(text='仅此一次').click()
            z.sleep(1)
            while d(text='登录中').exists:
                z.sleep(2)
            z.sleep(4)
            z.heartbeat()
            if d(resourceId='com.tencent.mobileqq:id/name',
                 index='2',
                 className="android.widget.EditText").exists:  # 需要验证码的情况
                icode = imageCode()
                im_id = ""
                for i in range(0, 30, +1):  # 打码循环
                    if i > 0:
                        icode.reportError(im_id)
                    obj = d(resourceId='com.tencent.mobileqq:id/name',
                            className='android.widget.ImageView'
                            )  #当弹出选择QQ框的时候,定位不到验证码图片
                    obj = obj.info
                    obj = obj['bounds']  # 验证码处的信息
                    left = obj["left"]  # 验证码的位置信息
                    top = obj['top']
                    right = obj['right']
                    bottom = obj['bottom']

                    d.screenshot(sourcePng)  # 截取整个输入验证码时的屏幕

                    img = Image.open(sourcePng)
                    box = (left, top, right, bottom)  # left top right bottom
                    region = img.crop(box)  # 截取验证码的图片

                    img = Image.new('RGBA', (right - left, bottom - top))
                    img.paste(region, (0, 0))

                    img.save(codePng)
                    im = open(codePng, 'rb')

                    codeResult = icode.getCode(im,
                                               icode.CODE_TYPE_4_NUMBER_CHAR)

                    code = codeResult["Result"]
                    im_id = codeResult["Id"]
                    os.remove(sourcePng)
                    os.remove(codePng)
                    z.heartbeat()
                    d(resourceId='com.tencent.mobileqq:id/name',
                      index='2',
                      className="android.widget.EditText").set_text(code)
                    z.sleep(3)
                    d(text='完成',
                      resourceId='com.tencent.mobileqq:id/ivTitleBtnRightText'
                      ).click()
                    z.sleep(6)
                    z.heartbeat()
                    while d(className='android.widget.ProgressBar',
                            index=0).exists:  #网速不给力时,点击完成后仍然在加载时的状态
                        z.sleep(2)
                    z.sleep(3)
                    z.heartbeat()
                    if d(text='输入验证码',
                         resourceId='com.tencent.mobileqq:id/ivTitleName'
                         ).exists:
                        continue
                    else:
                        break

            else:
                d.server.adb.cmd("shell",
                                 "am force-stop com.tencent1314.mobileqq"
                                 ).communicate()  # 强制停止
                z.sleep(1)
                d.server.adb.cmd(
                    "shell",
                    "am start -n com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity"
                ).communicate()  # 拉起来
                z.sleep(4)
            z.heartbeat()
            if d(text='搜索', resourceId='com.tencent.mobileqq:id/name'
                 ).exists:  # 不需要验证码的情况
                return QQNumber
            z.sleep(1)
            if d(text='马上绑定').exists:
                return QQNumber
            z.sleep(1)
            if d(text='通讯录').exists:  #登陆上后弹出t通讯录的情况
                return QQNumber
            if d(textContains='更换主题').exists:
                return QQNumber
            if d(text='寻找好友').exists:
                return QQNumber
            if d(textContains='密码错误').exists:
                self.logger.info('===========密码错误==============帐号:%s,密码:%s' %
                                 (QQNumber, QQPassword))
            z.heartbeat()
            self.repo.BackupInfo(cate_id, 'frozen', QQNumber, '',
                                 '')  # 仓库号,使用中,QQ号,设备号_卡槽号QQNumber
            z.sleep(1)
            if d(text='帐号无法登录').exists:
                d(text='取消').click()
            continue

    def action(self, d, z, args):
        z.heartbeat()
        d.dump(compressed=False)
        time_limit = args['time_limit']
        cate_id = args["repo_cate_id"]
        slotnum = self.slot.getEmpty()  # 取空卡槽

        print(slotnum)
        if slotnum == 0:  #没有空卡槽的话
            slotnum = self.slot.getSlot(d, time_limit)  # 没有空卡槽,取2小时没用过的卡槽
            print(slotnum)
            while slotnum == 0:  # 2小时没有用过的卡槽也为空的情况
                d.server.adb.cmd(
                    "shell",
                    "am broadcast -a com.zunyun.zime.toast --es msg \"QQ卡槽全满,无间隔时间段未用\""
                ).communicate()
                z.heartbeat()
                z.sleep(30)
                slotnum = self.slot.getSlot(d, time_limit)
            z.heartbeat()
            d.server.adb.cmd(
                "shell", "pm clear com.tencent.mobileqq").communicate()  # 清除缓存

            getSerial = self.repo.Getserial(
                cate_id, '%s_%s_%s' %
                (d.server.adb.device_serial(), self.type, slotnum))  #得到之前的串号
            time.sleep(1)
            if len(getSerial) == 0:  #之前的信息保存失败的话
                d.server.adb.cmd(
                    "shell",
                    "am broadcast -a com.zunyun.zime.toast --es msg \"串号获取失败,重新设置\""
                ).communicate()  #在51上测时库里有东西但是王红机器关闭后仍获取失败
                print('切换失败')
                getSerial = z.generateSerial("788")  # 修改信息
            else:
                getSerial = getSerial[0]['imei']  #如果信息保存成功但串号没保存成功的情况
                print('卡槽切换时的sereial%s' % getSerial)
                if getSerial is None:  #如果串号为空,在该卡槽下保存新的串号
                    getSerial = z.generateSerial("788")  # 修改信息
                else:
                    z.generateSerial(getSerial)  # 将串号保存
            z.heartbeat()
            self.slot.restore(d, slotnum)  # 有time_limit分钟没用过的卡槽情况,切换卡槽
            z.heartbeat()
            while True:
                ping = d.server.adb.cmd("shell",
                                        "ping -c 3 baidu.com").communicate()
                print(ping)
                if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                    break
                z.sleep(2)
            d.server.adb.cmd(
                "shell",
                "am broadcast -a com.zunyun.zime.toast --es msg \"卡槽成功切换为" +
                str(slotnum) + "号\"").communicate()
            z.sleep(2)
            if d(textContains='主题装扮').exists:
                d(text='关闭').click()
                z.sleep(1)

            d.server.adb.cmd(
                "shell",
                "am start -n com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity"
            ).communicate()  # 拉起来
            z.sleep(2)
            z.heartbeat()
            while d(textContains='正在更新数据').exists:
                z.sleep(2)
            z.sleep(5)
            z.heartbeat()
            if d(textContains='主题装扮').exists:
                d(text='关闭').click()
                z.sleep(1)

            loginedFlag = True

            seconds = 15
            while seconds > 0:
                z.toast('检查是否出现登录界面%s' % seconds)
                seconds = seconds - 1
                z.sleep(1)

                if z.checkTopActivity("com.tencent.mobileqq/.activity.RegisterGuideActivity") \
                    or z.checkTopActivity("com.tencent.mobileqq/.activity.LoginActivity") \
                    or d(textContains='身份过期').exists:
                    loginedFlag = False
                    break

            obj = self.slot.getSlotInfo(d, slotnum)  # 得到切换后的QQ号
            QQnumber = obj['info']  # info为QQ号
            if loginedFlag:
                z.toast(u'卡槽恢复成功')
                z.heartbeat()
                self.slot.backup(d, slotnum, QQnumber)  # 设备信息,卡槽号,QQ号
                self.repo.BackupInfo(cate_id, 'using', QQnumber, getSerial,
                                     '%s_%s_%s' %
                                     (d.server.adb.device_serial(), self.type,
                                      slotnum))  # 仓库号,状态,QQ号,备注设备id_卡槽id
            else:  #切换不成功的情况
                #z.toast(u'卡槽恢复失败,开始补登')
                self.repo.BackupInfo(cate_id, 'frozen', QQnumber, '',
                                     '')  # 标记卡槽号码为冻结,仓库号,状态,QQ号,备注设备id_卡槽id
                z.cmd("shell", "pm clear com.tencent.mobileqq")  # 清除缓存
                serialinfo = z.generateSerial("788")  # 修改信息
                z.heartbeat()
                z.toast(u'卡槽恢复失败,开始补登')
                QQnumber = self.login(d, args, z)  # 帐号无法登陆则登陆,重新登陆
                if QQnumber:
                    self.slot.backup(
                        d, slotnum,
                        QQnumber)  # 登陆之后备份,将备份后的信息传到后台 仓库号,状态,QQ号,备注设备id_卡槽id
                    self.repo.BackupInfo(
                        cate_id, 'using', QQnumber, serialinfo,
                        '%s_%s_%s' % (d.server.adb.device_serial(), self.type,
                                      slotnum))  # 仓库号,使用中,QQ号,设备号_卡槽号

                else:
                    z.toast(u'补登失败了 :(')

        else:  # 有空卡槽的情况
            d.server.adb.cmd(
                "shell", "pm clear com.tencent.mobileqq").communicate()  # 清除缓存

            z.heartbeat()
            while True:
                ping = d.server.adb.cmd("shell",
                                        "ping -c 3 baidu.com").communicate()
                print(ping)
                if 'icmp_seq' and 'bytes from' and 'time' in ping[0]:
                    break
                z.sleep(2)
            serialinfo = z.generateSerial("788")  #修改串号等信息
            print('登陆时的serial%s' % serialinfo)
            z.heartbeat()
            QQnumber = self.login(d, args, z)
            z.heartbeat()
            self.slot.backup(d, str(slotnum) + '_' + QQnumber)  #设备信息,卡槽号,QQ号
            self.repo.BackupInfo(cate_id, 'using', QQnumber, serialinfo,
                                 '%s_%s_%s' %
                                 (d.server.adb.device_serial(), self.type,
                                  slotnum))  # 仓库号,使用中,QQ号,设备号_卡槽号

        if (args["time_delay"]):
            z.sleep(int(args["time_delay"]))
예제 #17
0
    p = {
        "x1": 37 / width,
        "y1": 380 / height,
        "x2": 502 / width,
        "y2": 473 / height
    }
    z.img_crop(source, p)

    out = d.server.adb.run_cmd('shell', 'ls')
    z.input("xxx")
    #    d.server.adb.cmd("shell", "ime set com.zunyun.zime/.ZImeService").communicate()
    z.server.install()

    slot = Slot('cda0ae8d', 'mobileqq')
    print(slot.getSlots())
    slot.backup('21', '22221111')

    print(slot.getSlots())
    slot.clear('21')

    z.generateSerial()
    #z.input("6565wv=1027&k=48KHKLm")

    #d.server.adb.cmd("shell", "am", "start", "-a", "zime.clear.contacts").communicate()
    d.server.adb.cmd("shell",
                     "pm clear com.android.providers.contacts").communicate()
    #d.server.adb.cmd("push", filename, "/data/local/tmp/contacts.txt").communicate()
    d.server.adb.cmd("shell", "am", "start", "-n",
                     "com.zunyun.zime/.ImportActivity", "-t", "text/plain",
                     "-d", "/data/local/tmp/contacts.txt").communicate()