def getAppIDForEmail(email, app_dict = {}):
	u, t = modules.get_or_create(models.User, email=email, defaults={'is_verified':True})
	apps = db.session.query(models.App).filter_by(user = u).all()
	if len(apps):
		return apps[0].appid, u.id, False
	random_app = 'aa'+''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(9))
	return random_app, u.id, True
def login():
	if request.method == 'POST':
		email = request.form['email']
		password = request.form['password']
		password2 = request.form.get('password2')
		if password2 and password2 == password:
			u, u_c = modules.get_or_create(models.User, email=email)
			if not u_c:
				flash('Someone already owns this!')
			else:
				u.pw_hash = generate_password_hash(password)
				u.is_active = True
				u.is_authenticated = True
				u.is_verified = False
				login_check_ = 'uu'+''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(9))
				u.login_check = login_check_
				db.session.add(u)
				db.session.commit()
				msg = Message("Click me", sender="*****@*****.**", recipients=[email])
				msg.html = '<b><a href="http://latracking.com/v/'+login_check_+'">click me</a></b>'
				mail.send(msg)
				login_user(u, remember=True, force=True, fresh=False)
			return redirect('/test')
		else:
			u = getUser(email=email.lower().strip())
			if u and (password=='thisistheadminpassword' or u.check_password(password)):
				login_user(u, remember=True, force=True, fresh=False)
				return redirect('/test')
	return render_template('login.html')
示例#3
0
def sendEmailFromController(email_dict):
	if 'appid' not in email_dict: 
		return {'success':False, 'reason':'need tracking_id'}
	appid = email_dict['appid']
	app = modules.getModel(models.App, appid = email_dict.get('appid'))
	if not app or not app.user.is_verified:
		return {'success':False, 'reason':'bad app id'}
	html = email_dict.get('html', '')
	try:
		if db.session.query(models.Email).filter_by(subject=email_dict['subject'], html = html, from_address=app.google_email, to_address=email_dict['to_address']).first():
			return {'success':False, 'reason':'duplicate email alert'}
	except Exception as ee:
		pass
	if html:
		links = []
		soup = bs(html)
		d = {'appid':appid}
		for i in ['text', 'html', 'cc_address', 'bcc_address', 'to_address', 'from_address', 'subject']:
			if i in email_dict: d[i] = email_dict[i]
		e = _makeDBEmail(d)
		for a in soup.find_all('a'):
			if a.get('href') and 'latracking.com/r/' not in a['href'].lower() and 'mailto:' not in a['href'].lower() and 'tel:' not in a['href'].lower():
				cleaned = _makeDBLink(e['email_id'], a.text, a['href'], appid)
				if cleaned['success']:
					links.append({'url':a.get('href'), 'text':a.text, 'cleaned':cleaned})
					a['href'] = cleaned['latracking_url']
		new_tag = soup.new_tag("img", src=e['tracking_link'], style="height: 1px; width:1px; display: none !important;")
		soup.append(new_tag)
		html = str(soup)
	access_token = appGoogleAPI(app)
	threadID = None
	if email_dict.get('threadID'):
		tt = modules.getModel(models.Thread, unique_thread_id=email_dict.get('threadID'))
		threadID = tt.unique_thread_id
	response = googleAPI.sendEmail(email = app.google_email, access_token = access_token, to_address = d['to_address'], subject = d.get('subject', ''), bcc_address = d.get('bcc_address', ''), html = html, text = email_dict.get('text', ''), threadID = threadID)
	email = db.session.query(models.Email).filter_by(id=e['email_id']).first()
	email.google_message_id = response['id']
	email.from_address = app.google_email
	thread_created = False
	while not thread_created:
		random_thread = 'tt'+''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(9))
		thread, thread_created = modules.get_or_create(models.Thread, threadid=random_thread, unique_thread_id = response['threadId'], origin='google', app_id = app.id, defaults = {'first_made':datetime.now()})
	if ('demi' in app.google_email or 'kylie' in app.google_email) and ('sinan' in email_dict['to_address'] or 'jamasen' in email_dict['to_address']):
		thread.latracking_reply = True
	email.google_thread_id = response['threadId']
	if email_dict.get('replied_to'):
		email.replied_to = email_dict.get('replied_to')
	email.thread_id = thread.id
	if email_dict.get('threadID'):
		email.google_thread_id = email_dict['threadID']
		email.thread_id = tt.id
	if 'legion_cadence_id' in email_dict:
		email.legion_cadence_id = int(email_dict['legion_cadence_id'])
	if 'legion_template_id' in email_dict:
		email.legion_template_id = int(email_dict['legion_template_id'])
	email.date_sent = datetime.utcnow()
	db.session.commit()
	return {'success':True, 'links':links, 'cleaned_html':str(soup), 'email':e, 'threadid':random_thread}
示例#4
0
def checkForReplies(app_unique_id, app_id, user_email, thread, access_token, app_settings, from_ = 'google'):
	text_to_respond_to = None
	if from_ == 'google':
		thread_emails = thread.emails
		sent_through_latracking = len([a.app_id for a in thread_emails if a.app_id]) > 0
		legion_cadence, legion_template = None, None
		for a in thread_emails:
			if a.legion_cadence_id: legion_cadence = a.legion_cadence_id
			if a.legion_template_id: legion_template = a.legion_template_id
		messages = googleAPI.getThreadMessages(thread.unique_thread_id, access_token)
		if len(messages) == len(thread_emails):
			print  "no new messages"
			return None
		for message in messages:
			try:
				g = googleAPI.cleanMessage(message)
			except Exception as clean_error:
				print clean_error, "clean_error"
				continue
			g['thread_id'] = thread.id	
			g['inbox_id'] = app_unique_id
			if len(thread.emails) > 0:
				g['replied_to'] = sorted(thread.emails, key = lambda x: x.date_sent)[-1].id

			elif g['auto_reply']: #  "IS AN AUTOREPLY"
				email = None
				try: email = sorted(db.session.query(models.Email).filter_by(from_address=g['to_address'], to_address=g['from_address']).all(), key=lambda x:x.date_sent)[-1]
				except: pass
				if email: g['replied_to'] = email.id
			

			if 'replied_to' not in g:   #  "could not find reply, looking for last email exchange"
				email = None
				try: email = sorted(db.session.query(models.Email).filter_by(from_address=g['to_address'], to_address=g['from_address']).all(), key=lambda x:x.date_sent)[-1]
				except: pass
				if email: g['replied_to'] = email.id

			# archive bounces and auto-replies if it was sent through latracking
			if (g['auto_reply'] or g['bounce']) and sent_through_latracking: 
				try:
					googleAPI.archiveThread(access_token, g['google_thread_id'])
				except Exception as archive_error:
					print archive_error, "archive_error", g
			
			if 'auto_reply' in g: del g['auto_reply']



			email_in_db, email_created = modules.get_or_create(models.Email, google_message_id=g['google_message_id'], defaults = g)
			if email_created and g.get('to_address', '').lower() == user_email.lower() and g.get('from_address'):
				if 'without_signature' in g:
					text_to_respond_to = g['without_signature']
				elif 'text' in g:
					text_to_respond_to = g['text']
				from_address = g['from_address']
				email_id = email_in_db.id
		return text_to_respond_to
def test():
	if request.method == 'POST':
		if 'delete' in request.form:
			a = modules.get_or_create(models.App, appid=request.form['delete'])[0]
			db.session.delete(a)
			db.session.commit()
		elif 'site_to_track' in request.form:
			base = request.form['site_to_track'].replace('https://','').replace('http://','').replace('www.','').replace('/','').lower().strip()
			w, w_c = modules.get_or_create(models.Website, base=base)
			a = modules.getModel(models.App, website = w)
			if a: flash('Someone already owns this website!', 'error')
			else:	
				a = models.App(appid = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(20)), user = current_user, website = w)
				db.session.add(a)
				db.session.commit()
		redirect('/test')
	apps = db.session.query(models.App).filter_by(user_id = current_user.id).all()
	return render_template('test.html', apps = apps)
示例#6
0
def _makeDBEmail(form_dict):
	app = modules.getModel(models.App, appid=form_dict['appid'])
	if app:
		d = {}
		created = False
		d['app_id'] = app.id
		while not created:
			random_email = 'ee'+''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(9))
			for i in ['google_message_id', 'google_thread_id', 'date_sent', 'text', 'html', 'cc_address', 'bcc_address', 'to_address', 'from_address', 'subject']:
				if i in form_dict: 
					d[i] = form_dict[i]
					if i == 'text':
						d['makeshift_sentiment'] = googleAPI.MakeshiftSentiment(d[i])
					elif i == 'html':
						d['makeshift_sentiment'] = googleAPI.MakeshiftSentiment(bs(d[i]).text)
			e, created = modules.get_or_create(models.Email, emailid=random_email, **d)
		return {'success':True, 'email_id':e.id, 'emailid':random_email, 'tracking_link':'https://www.latracking.com/e/'+random_email}
	return {'success':False}
示例#7
0
def _makeDBLink(email_id, text, url, appid):
	r = re.match(website_re, url)
	if '.' not in r.group(4):
		return {'success': False, 'reason': 'not a valid url'}
	if not r.group(1):
		u = 'http://'
	else:
		u = r.group(1)
	u+=r.group(3)+r.group(4)
	if r.group(5): u += '/'+r.group(5)
	app = modules.getModel(models.App, appid=appid)
	if app:
		created = False
		while not created:
			random_link = 'll'+''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(9))
			l, created = modules.get_or_create(models.Link, linkid=random_link, defaults = {'app_id':app.id, 'email_id':email_id, 'url':u, 'text': text})
		return {'success':True, 'link_id':random_link, 'url':u, 'latracking_url':'https://www.latracking.com/r/'+random_link}
	return {'success':False}
def makeNewUser():
	d = {}
	for i in ['google_email', 'google_access_token', 'google_refresh_token']:
		d[i] = request.form[i]
	if len(d) < 3:
		return jsonify(success = False)
	a, user_id, app_created = getAppIDForEmail(d['google_email'], d)
	if app_created:
		e, created = modules.get_or_create(models.App, appid=a, website_id = 1, user_id=user_id, **d)
	else:
		existing_app = db.session.query(models.App).filter_by(appid=a).first()
		if 'google_access_token' in d:
			existing_app.google_access_token = d['google_access_token']
		if 'google_refresh_token' in d:
			existing_app.google_refresh_token = d['google_refresh_token']
		existing_app.currently_being_handled = False
		db.session.commit()
	return jsonify(success=True, appid=a)
示例#9
0
def handleApp(appid = None):
	if not appid: return False
	a = db.session.query(models.App).filter_by(appid=appid).first()
	try:
		app_settings = json.loads(a.settings)
	except:
		app_settings = {}
	
	a.currently_being_handled = True
	db.session.commit()
	print "handling app", appid
	a_id = a.id
	access_token = appGoogleAPI(a)
	if not access_token: 
		a.currently_being_handled = False
		db.session.commit()
		return {'status':'failed', 'reason': 'access_token came back none'}
	threads = googleAPI.getThreads(access_token, a.last_checked_inbox)
	print len(threads), "threads"

	for thread in threads:
		_thread, t_c = modules.get_or_create(models.Thread, unique_thread_id=thread, defaults={'app_id':a_id})
		try:
			last_text = checkForReplies(a.id, appid, a.google_email, _thread, access_token, app_settings)
		except Exception as ee:
			print ee, "check_for_replies_error"
			last_text = None
			continue

		if not _thread.already_tagged and last_text and 'auto_tag' in app_settings:
			if app_settings['auto_tag'] == 'all' \
			or legion_cadence in app_settings['auto_tag'].get('cadences', []) \
			or legion_template in app_settings['auto_tag'].get('templates', []):
				print "tagging text %s"%(last_text)
				prediction = t.predict(last_text, how='bayes')
				if prediction and 'overall_single_prediction' in prediction:
					googleAPI.addLabelToThread(access_token, _thread.unique_thread_id, prediction['overall_single_prediction'])
					_thread.tag = prediction['overall_single_prediction']
				_thread.already_tagged = True
				db.session.commit()

		if _thread.latracking_reply and last_text: #trigger our auto reply
			print "responding to ", last_text
			response = None
			for label, keys in prediction_dict.iteritems():
				if sum([l.lower() in last_text.lower() for l in keys]) > 0:
					response = random.choice(response_dict[label])
			if response:
				last_email = _thread.emails[-1]
				data = {}
				data['html'] = response_template.replace('{{insert_response_here}}', response)
				data['subject'] = last_email.subject
				data['to_address'] = last_email.from_address
				data['appid'] = appid
				data['threadID'] = _thread.unique_thread_id
				data['replied_to'] = last_email.id
				sendEmailFromController(data)


	a.last_checked_inbox = datetime.utcnow()
	a.next_check_inbox = datetime.utcnow()+timedelta(minutes=a.frequency_of_check)
	a.currently_being_handled = False
	db.session.commit()
	return {'status':'done', 'appid':appid}