예제 #1
0
파일: playweka.py 프로젝트: tvldz/playweka
def main():
    search_term = sys.argv[1]
    '''
    apps will be a list of dicts describing each returned app:
    {'app_name':<app name>,'app_id':<app id>,'app_creator':<creator>,'app_permissions':[list]}
    '''
    apps = []
    nb_res = 100 # apps to retrieve. API allows for max of 100.
    offset = 0 
    api = GooglePlayAPI(ANDROID_ID)
    api.login(GOOGLE_LOGIN, GOOGLE_PASSWORD, AUTH_TOKEN)
    try:
        message = api.search(search_term, nb_res, offset)
    except:
        print "Error: something went wrong. Google may be throttling or rejecting the request."
        sys.exit(1)

    doc = message.doc[0]
    for c in doc.child:
        permissions = []
        details = api.details(c.docid)
        for line in details.docV2.details.appDetails.permission:
            permissions.append(line)
        apps.append({'app_name':c.title,'app_id':c.docid,'app_creator':c.creator,'app_permissions':permissions})

    '''
    We are interested in the set of all possible permissions that start with 'ANDROID.'
    '''
    permissions = Set([])
    for app in apps:
        for permission in app["app_permissions"]:
            if  permission.upper()[0:8] == "ANDROID.":
                permissions.add(permission.upper())

    '''
    Create ARFF output for Weka
    '''
    dataset = open(search_term + ".arff",'w')
    dataset.write("@relation Appdata\n")
    dataset.write("@attribute index NUMERIC\n")
    dataset.write("@attribute app_name STRING\n")
    for att in permissions:
        dataset.write("@attribute "+ att + " {0,1}\n")
    dataset.write("@data\n")
    i = 0 # index for cross-referencing
    for app in apps:
        print("{} {}").format(str(i), str(app)) # index
        perm_str = str(i) + ',' + app['app_id'] + ','
        app_perm_upper = []
        for app_permission in app['app_permissions']:
            app_perm_upper.append(app_permission.upper())
        for permission in permissions:
            if permission in app_perm_upper:
                perm_str = perm_str + '1,'
            else:
                perm_str = perm_str + '0,'
        dataset.write(perm_str[:-1])
        dataset.write("\n")
        i += 1
예제 #2
0
def findAppInfo(packageName):
    request = packageName
    nb_res = None
    offset = None

    api = GooglePlayAPI(ANDROID_ID)
    api.login(GOOGLE_LOGIN, GOOGLE_PASSWORD, AUTH_TOKEN)

    try:
        message = api.search(request, nb_res, offset)
        doc = message.doc[0]
        for c in doc.child:
            if c.docid.startswith(packageName):
                result = {}
                result["creator"] = c.creator
                result["price"] = c.offer[0].formattedAmount
                return result
    except Exception, e:
        print str(e)
예제 #3
0
def findAppInfo(packageName):
    request = packageName
    nb_res = None
    offset = None

    api = GooglePlayAPI(ANDROID_ID)
    api.login(GOOGLE_LOGIN, GOOGLE_PASSWORD, AUTH_TOKEN)

    try:
        message = api.search(request, nb_res, offset)
        doc = message.doc[0]
        for c in doc.child:
            if c.docid.startswith(packageName):
                result = {}
                result["creator"] = c.creator
                result["price"] = c.offer[0].formattedAmount
                return result
    except Exception, e:
        print str(e)
    print "Usage: %s request [nb_results] [offset]" % sys.argv[0]
    print "Search for an app."
    print "If request contains a space, don't forget to surround it with \"\""
    sys.exit(0)

request = sys.argv[1]
nb_res = None
offset = None

if (len(sys.argv) >= 3):
    nb_res = int(sys.argv[2])

if (len(sys.argv) >= 4):
    offset = int(sys.argv[3])

api = GooglePlayAPI(ANDROID_ID)
api.login(GOOGLE_LOGIN, GOOGLE_PASSWORD, AUTH_TOKEN)

try:
    message = api.search(request, nb_res, offset)
except:
    print "Error: something went wrong. Maybe the nb_res you specified was too big?"
    sys.exit(1)

print_header_line()
print message
doc = message.doc[0]
for c in doc.child:
    print_result_line(c)

예제 #5
0
     NB_RES = int(sys.argv[2])

if (len(sys.argv) >= 4):
     OFFSET = int(sys.argv[3])
    
# Check request content   
print "Request:", request
print "Number of request:", NB_RES
print "Offset:", OFFSET


api = GooglePlayAPI(ANDROID_ID)
api.login(GOOGLE_LOGIN, GOOGLE_PASSWORD, AUTH_TOKEN)
print "NB_RES/OFFSET:",NB_RES/OFFSET
for i in range (50):
    message = api.search(request, str(NB_RES), str(i*NB_RES))
    doc = message.doc[0]
    for c in doc.child:
        print c
        l = [           
                # unicode type
                c.docid,
                c.title,
                c.creator,
                c.descriptionHtml, # need to remove control characters
                c.offer[0].formattedAmount,
                            
                c.details.appDetails.versionCode, # long type
                c.details.appDetails.versionString,   #unicode type
                c.details.appDetails.appCategory, # class type
                c.details.appDetails.installationSize, # long type
예제 #6
0
def crawlAll(id, offset=0):
    # declared as global in order for changes to be acknowledged by every threads
    global FOUND_APP
    global LOCK
    global TOTAL_SIZE
    global THREAD_PROGRESS

    api = GooglePlayAPI(ANDROID_ID[id])
    api.login(GOOGLE_LOGIN[id], GOOGLE_PASSWORD[id], AUTH_TOKEN)
    user = id

    for wordId in range(offset, len(SPLITED_DICO[id])):

        try:
            message = api.search(SPLITED_DICO[id][wordId],
                                 250)  # Search the playstore with the word
        except:
            print "Error: HTTP 500 - one of the provided parameters is invalid"
            return 0

        try:
            doc = message.doc[0]
        except IndexError:  # if we were blocked
            print "Blocked, switching Account"
            connected = 0
            while (connected == 0):
                user += THREAD_NUMBER
                if user >= len(ANDROID_ID):
                    user = id
                print GOOGLE_LOGIN[user]

                time.sleep(4)  # Wait a bit before connecting again
                del api
                api = GooglePlayAPI(ANDROID_ID[user], LANG)
                try:
                    api.login(GOOGLE_LOGIN[user], GOOGLE_PASSWORD[user],
                              None)  # attempt another connection
                    connected = 1
                except LoginError:
                    connected = 0
                    print "Auth error, retrying ..."

            continue

        for c in doc.child:
            try:
                #print_result_line(c)

                package = c.docid
                while LOCK == 1:  # prevent reading while other thread is writing
                    pass
                if package in FOUND_APP:  # if app was found in a previous search
                    continue
                name = c.title
                length = c.details.appDetails.installationSize / float(
                    1024 * 1024)
                TOTAL_SIZE += length

                l = [package, name, str(length) + "MB"]
                print SEPARATOR.join(unicode(i).encode('utf8') for i in l)

                while LOCK == 1:  # prevent writing when other thread is writing
                    pass
                LOCK = 1  # Acquire lock
                FOUND_APP.append(package)  # commit change
                LOCK = 0  # release lock

                print "\nNumber Of app = " + str(len(FOUND_APP))
                print "\nAverage size Of app = " + str(
                    TOTAL_SIZE / len(FOUND_APP))

                if length > 0:  # if apk is more than 1 MB
                    print 'too large, skip'
                    continue

                folder = DOWNLOAD_PATH
                if not os.path.exists(folder):
                    os.mkdir(folder)
                filename = folder + '/' + name + '.apk'
                if not os.path.isfile(filename):
                    downloadApps(api, package, filename)

            except:
                continue
        THREAD_PROGRESS[id] = wordId
        print "processed words by thread #" + str(id) + ": " + str(
            THREAD_PROGRESS[id])
    return FOUND_APP
예제 #7
0
if (len(sys.argv) < 2):
    print "Usage: %s request [nb_results] [offset]" % sys.argv[0]
    print "Search for an app."
    print "If request contains a space, don't forget to surround it with \"\""
    sys.exit(0)

request = sys.argv[1]
nb_res = None
offset = None

if (len(sys.argv) >= 3):
    nb_res = int(sys.argv[2])

if (len(sys.argv) >= 4):
    offset = int(sys.argv[3])

api = GooglePlayAPI(ANDROID_ID)
api.login(GOOGLE_LOGIN, GOOGLE_PASSWORD, AUTH_TOKEN)

try:
    message = api.search(request, nb_res, offset)
except:
    print "Error: something went wrong. Maybe the nb_res you specified was too big?"
    sys.exit(1)

print_header_line()
doc = message.doc[0]
for c in doc.child:
    print_result_line(c)

예제 #8
0
def retrieveCategoryPackageNames(request):

    nb_res = None
    offset = None
    api = GooglePlayAPI(ANDROID_ID)
    api.login(GOOGLE_LOGIN, GOOGLE_PASSWORD, AUTH_TOKEN)


    packageNamesList = []
    #print_header_line()

    # continue requesting until receive ALL apps by category. use to make histogram.
    while True:
        try:
            message = api.search(request, nb_res, offset)
        except:
            break

        if message.doc:
            doc = message.doc[0]

            for c in doc.child:
                packageNamesList.append(c.docid)
            offset = len(packageNamesList)
        else:
            break

    dic = {}
    final_results = {}

    # Only one app returned TODO update this
    if (len(packageNamesList) == 1):
        response = api.details(packageNamesList[0])
        print "\n".join(i.encode('utf8') for i in response.docV2.details.appDetails.permission)

    # More than one app
    else:
        response = api.bulkDetails(packageNamesList)

        for entry in response.entry:
            hasCustom = False
            if (entry.ListFields()):
                iconUrl = ""
                for x in entry.doc.image:
                    if x.imageType == 4:
                        iconUrl = x.imageUrl
                final_results[entry.doc.docid] = {'package': entry.doc.docid, 'title':entry.doc.title, 
                                          'creator':entry.doc.creator, 
                                          'price':{'amount':entry.doc.offer[0].formattedAmount, 'currency':entry.doc.offer[0].currencyCode}, 
                                          'icon':iconUrl,
                                          'permissions':[perm for perm in entry.doc.details.appDetails.permission],
                                          'rating':{'stars':entry.doc.aggregateRating.starRating, 'count':entry.doc.aggregateRating.ratingsCount},
                                          'shareUrl': entry.doc.shareUrl 
                                          }
                for permission in entry.doc.details.appDetails.permission:
                    # apps can have custom permissions that don't start with android.permission.PERM_NAME_HERE
                    # are they safe? Will warn users about custom permissions.
                    perm = permission.split(".")
                    if (permission != "com.android.browser.permission.WRITE_HISTORY_BOOKMARKS" and permission != "com.android.browser.permission.WRITE_HISTORY_BOOKMARKS" and (len(perm) !=3 or perm[0] != "android" or perm[1] != "permission")):
                        hasCustom = True
                        continue # don't want to count custom permissions in the histogram dictionary since they will all of them will be unusual
                    #perm = perm[-2] + "." + perm[-1]
                    if permission in dic:
                        dic[permission] += 1;
                    else:
                        dic[permission] = 1;
                final_results[entry.doc.docid]['custom'] = hasCustom
    #print dic

    DANGEROUS_PERMS = ["android.permission.ACCESS_COARSE_LOCATION",
                       "android.permission.ACCESS_FINE_LOCATION",
                       "android.permission.ACCESS_MOCK_LOCATION",
                       "android.permission.AUTHENTICATE_ACCOUNTS",
                       "android.permission.BLUETOOTH",
                       "android.permission.BLUETOOTH_ADMIN",
                       "android.permission.CALL_PHONE",
                       "android.permission.CAMERA",
                       "android.permission.CHANGE_CONFIGURATION",
                       "android.permission.CHANGE_NETWORK_STATE",
                       "android.permission.CHANGE_WIFI_MULTICAST_STATE",
                       "android.permission.CHANGE_WIFI_STATE",
                       "android.permission.CLEAR_APP_CACHE",
                       "android.permission.DUMP",
                       "android.permission.GET_TASKS",
                       "android.permission.INTERNET",
                       "android.permission.MANAGE_ACCOUNTS",
                       "android.permission.MODIFY_AUDIO_SETTINGS",
                       "android.permission.MODIFY_PHONE_STATE",
                       "android.permission.MOUNT_FORMAT_FILESYSTEMS",
                       "android.permission.MOUNT_UNMOUNT_FILESYSTEMS",
                       "android.permission.PERSISTENT_ACTIVITY",
                       "android.permission.PROCESS_OUTGOING_CALLS",
                       "android.permission.READ_CALENDAR",
                       "android.permission.READ_CONTACTS",
                       "android.permission.READ_LOGS",
                       "android.permission.READ_OWNER_DATA",
                       "android.permission.READ_PHONE_STATE",
                       "android.permission.READ_SMS",
                       "android.permission.READ_USER_DICTIONARY",
                       "android.permission.RECEIVE_MMS",
                       "android.permission.RECEIVE_SMS",
                       "android.permission.RECEIVE_WAP_PUSH",
                       "android.permission.RECORD_AUDIO",
                       "android.permission.REORDER_TASKS",
                       "android.permission.SEND_SMS",
                       "android.permission.SET_ALWAYS_FINISH",
                       "android.permission.SET_ANIMATION_SCALE",
                       "android.permission.SET_DEBUG_APP",
                       "android.permission.SET_PROCESS_LIMIT",
                       "android.permission.SET_TIME_ZONE",
                       "android.permission.SIGNAL_PERSISTENT_PROCESSES",
                       "android.permission.SUBSCRIBED_FEEDS_WRITE",
                       "android.permission.SYSTEM_ALERT_WINDOW",
                       "android.permission.USE_CREDENTIALS",
                       "android.permission.WAKE_LOCK",
                       "android.permission.WRITE_APN_SETTINGS",
                       "android.permission.WRITE_CALENDAR",
                       "android.permission.WRITE_CONTACTS",
                       "android.permission.WRITE_EXTERNAL_STORAGE",
                       "android.permission.WRITE_OWNER_DATA",
                       "android.permission.WRITE_SETTINGS",
                       "android.permission.WRITE_SMS",
                       "android.permission.WRITE_SYNC_SETTINGS",
                       "com.android.browser.permission.READ_HISTORY_BOOKMARKS",
                       "com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"]
    #go through final_results and add field for unusual permissions
    for docid in final_results: 
        final_results[docid]['unusual'] = False
        final_results[docid]['dangerous'] = False
        for permission in final_results[docid]['permissions']:
            perm = permission.split(".")
            if (permission != "com.android.browser.permission.WRITE_HISTORY_BOOKMARKS" and permission != "com.android.browser.permission.WRITE_HISTORY_BOOKMARKS" and (len(perm) !=3 or perm[0] != "android" or perm[1] != "permission")):
                continue
            elif dic[permission] < 0.05*offset:
                final_results[docid]['unusual'] = True
                if 'unusual_perms' in final_results[docid]:
                    final_results[docid]['unusual_perms'].append(permission)
                else:
                    final_results[docid]['unusual_perms'] = [permission]
                if permission in DANGEROUS_PERMS:
                    final_results[docid]['dangerous'] = True
                    if 'dangerous_permissions' in final_results[docid]:
                        final_results[docid]['dangerous_permissions'].append(permission)
                    else:
                        final_results[docid]['dangerous_permissions'] = [permission]

    final = json.dumps({"app": final_results.values()})
    print final
    return None