#!/usr/bin/env python3 import os, sys import tempfile import argparse from collections import Counter from pathlib import Path import utils.console as console import utils.config as cfg from grabber.facebook import FBGrabber, FBProfileGrabber from grabber.google import GoogleGrabber from grabber.yandex import YandexGrabber from grabber.imageraider import ImageRaiderGrabber from grabber.pictriev import PictrievGrabber from grabber.instagram import InstagramGrabber from face_recog import FaceRecog import subprocess, json, shutil from report.report import makeReport, makeJSONReport def presentResult(predictions): if len(predictions) > 0: argmax = Counter(predictions) console.section("Result") if len(argmax.most_common(n=1)) > 0: (most_common_str, _) = argmax.most_common(n=1)[0] else: most_common_str = 'None' console.task("Google says it could be: {0}".format(most_common_str)) else: console.failure("No predictions found") def filterInstaLinks(links): r = [] for l in links: if "instagram.com" in l: r.append(l) return r def parseInstaUsername(links): usernames = [] for l in links: a = l[8:] a = a.split('/') if len(a) >= 2: if len(a[1]) >= 4: usernames.append(a[1]) else: console.subfailure('Error parsing {0}'.format(l)) return usernames def validateInstaUser(username, num_jitters): images = getInstaLinks(username) if len(images) >= cfg.instaLimit(): images = images[:cfg.instaLimit()] r = FaceRecog(username, images, num_jitters=num_jitters) r.loadKnown(username) profile_links, _ = r.getValidLinksAndImg(username) return len(profile_links) > 0 def getInstaLinks(username): instagrabber = InstagramGrabber(username) return instagrabber.getLinks() def main(skipFB=False, skipIR=False, skipY=False, FBUrls=[], jsonRep=None): if not skipFB: # collect user input console.prompt('Enter the persons name to find on FB: ') name = input('') while not name: console.prompt('Enter the persons name to find on FB: ') name = input('') else: console.task('Skipping FB Search') name = "Unknown" console.prompt('How many jitters, higher is better [max 100] (default=70): ') num_jitters = input('') if not num_jitters: console.task('Settings jitters to 70') num_jitters = 70 num_jitters = int(num_jitters) if num_jitters > 100: console.subfailure('Dude wtf?!') num_jitters = 100 console.subfailure('Using 100 jitters...') if not skipFB: # grab profile urls f = FBGrabber(name) f.grabData() # do face recognition on those profile images r = FaceRecog(f.getProfileLinks(), f.getProfileImages(), num_jitters=num_jitters) r.loadKnown(name) profile_links, profile_imgs = r.getValidLinksAndImg(name) console.section('Result') console.task('Found the following Profiles:') for i in range(len(profile_links)): console.subtask(profile_links[i]) else: if len(FBUrls) > 0: f = FBProfileGrabber(FBUrls) img_urls = f.grabLinks() #FBURLS are our profile links synchron with img_urls # so FBURLS[0] <=> img_urls[0] r = FaceRecog(FBUrls, img_urls, num_jitters=num_jitters) r.loadKnown(name) profile_links, profile_imgs = r.getValidLinksAndImg(name) console.section('Result') console.task('Found the following Profiles:') for i in range(len(profile_links)): console.subtask(profile_links[i]) else: profile_links = [] profile_imgs = [] # google reverse image search on profile pics g = GoogleGrabber() for img in profile_imgs: g.collectLinks(img) # google reverse image search on reference pic g.collectLinksLocal() rev_links, predictions = g.finish() #TODO: Fix yandex search #if not skipY: if False: yandex = YandexGrabber() for img in profile_imgs: yandex.collectLinks(img) yandex.collectLinksLocal() #add to rev_links for e in yandex.finish(): rev_links.append(e) else: console.task('Skipping Yandex Search') rev_links = list(set(rev_links)) instaNames = parseInstaUsername(filterInstaLinks(rev_links)) validatedInstaNames = [] console.section("Validating Instagram Profiles") for un in instaNames: console.task("Validating Profile: '{0}'".format(un)) if validateInstaUser(un, num_jitters): validatedInstaNames.append(un) raider_img_list = profile_imgs for v in validatedInstaNames: l = getInstaLinks(v) for li in l: raider_img_list.append(li) if len(raider_img_list) <= 0: console.failure('No Links found...') else: if not skipIR: raider = ImageRaiderGrabber() raider.insertImageLinks(raider_img_list) raider.downloadCSV() raider_links = raider.processCSV() for raider_link in raider_links: rev_links.append(raider_link) else: console.task('Skipping ImageRaider Search') rev_links = list(set(rev_links)) predictions = list(set(predictions)) console.section('Links') print(rev_links) console.section('Predictions') try: predictions = [x.lower() for x in predictions] except: predictions = [] print(predictions) presentResult(predictions) for pl in profile_links: rev_links.append(pl) rev_links = list(set(rev_links)) #estimate age ageEstimator = PictrievGrabber() if len(validatedInstaNames) > 0: for v in validatedInstaNames: l = getInstaLinks(v) if len(l) >= cfg.instaLimit(): l = l[:cfg.instaLimit()] for li in l: ageEstimator.collectAges(li) age = ageEstimator.finish() else: console.failure('No Instagram Images to upload...') #ageEstimator.finish() age = "Unknown" if jsonRep: console.section("Dumping JSON Report") makeJSONReport(name, rev_links, predictions, validatedInstaNames, age, jsonRep) else: console.section("Creating PDF Report") makeReport(name, rev_links, predictions, validatedInstaNames, age) p = os.path.join(tempfile.gettempdir(), 'imageraider') if os.path.isdir(p): pathlist = Path(p).glob('**/*') for path in pathlist: s_p = str(path) os.remove(s_p) console.task("KTHXBYE") if __name__ == "__main__": console.banner() parser = argparse.ArgumentParser() parser.add_argument('-sFB', '--skipfb', action='store_true', help='Skips the Facebook Search') parser.add_argument('-sIR', '--skipir', action='store_true', help='Skips the ImageRaider Reverse Search') #parser.add_argument('-sY', '--skipyandex', action='store_true', help='Skips the Yandex Reverse Search') parser.add_argument('-json', '--json', nargs='?', help='Generates a json report. Specify a Filename') parser.add_argument('-fbList', '--facebookList', nargs='?', help="A file which contains Links to Facebook Profiles. '--skipfb' options must be enabled to use this" ) args = parser.parse_args() if args.json: jsonRepFile = args.json if os.path.isfile(jsonRepFile): console.failure("File '{}' already exists".format(jsonRepFile)) sys.exit(-1) else: jsonRepFile = None if args.facebookList and args.skipfb: if os.path.isfile(args.facebookList): with open(args.facebookList, 'r') as f: content = f.readlines() content = [x.strip() for x in content] #TODO: fix yandex #main(skipFB=args.skipfb, skipIR=args.skipir, skipY=args.skipyandex, FBUrls=content) main(skipFB=args.skipfb, skipIR=args.skipir, skipY=None, FBUrls=content, jsonRep=jsonRepFile) else: console.failure("File '{}' does not exist".format(args.facebookList)) sys.exit(-1) else: #TODO: fix yandex #main(skipFB=args.skipfb, skipIR=args.skipir, skipY=args.skipyandex, FBUrls=[]) main(skipFB=args.skipfb, skipIR=args.skipir, skipY=None, FBUrls=[], jsonRep=jsonRepFile)