def confirm(token): if current_user.confirmed: return redirect(url_for('main.index')) if current_user.confirm(token): flash(_('You have confirmed your account. Thanks!'), 'success') EmailUtil.send_new_user_email(user=current_user) else: flash(_('The confirmation link is invalid or has expired'), 'warning') return redirect(url_for('main.index'))
def register(): form = RegisterForm() if form.validate_on_submit(): user = User(email=form.email.data, username=form.username.data, password=form.password.data) db.session.add(user) db.session.commit() token = user.generate_confirmation_token() EmailUtil.send_confirm_email(user=user, token=token) flash(_('A confirmation email has been sent to you by email'), 'info') return redirect(url_for('auth.login')) return render_template('auth/register.html', form=form)
def reset_password_request(): if not current_user.is_anonymous: return redirect(url_for('main.index')) form = ResetPasswordRequestForm() if form.validate_on_submit(): user = User.query.filter_by(email=form.email.data).first() if user is not None: token = user.generate_password_reset_token() EmailUtil.send_reset_password_email(user=user, token=token, next=request.args.get(next)) flash(_('An email with instructions to reset ' 'your password has been sent to you'), 'info') return redirect(url_for('auth.login')) return render_template('auth/reset_password.html', form=form)
def change_email_request(): form = ChangeEmailForm() if form.validate_on_submit(): if current_user.verify_password(form.password.data): new_email = form.email.data # 将新设的邮箱账号保存到令牌中 token = current_user.generate_email_change_token(new_email) EmailUtil.send_change_email_email(new_email, user=current_user, token=token, next=request.args.get(next)) flash(_('An email with instructions to confirm your ' 'new email address has been sent to you.'), 'info') return redirect(url_for('main.index')) else: flash(_('Invalid email or password'), 'warning') return render_template('/auth/change_email.html', form=form)
def otp_email_send(data): """ To generate a OTP based on the details provided by the user and if the user email and phone matches generate a email which contails the OTP. """ user = AppUsers().get_user(data) if user: password = generate_otp(user) client = EmailUtil() user = { **user, **{ 'password': password, 'link': app.config['WEB_SITE_LINK'] } } msg = client.message(render_template('forgot_password.html', user=user), 'Recovery OTP', [user.get('email')], [], msg_type="html") client.send_mail(msg, [user.get('email')]) return make_response(jsonify({'status': 'success'}), 200) return make_response(jsonify({'status': 'unauthorized user'}), 200)
class RunTest: def __init__(self): self.cmd = Command() self.email_util = EmailUtil() self.alert = Alert() self.logger = Logger().get_logger() def main(self): time_stamp = str(int(time.time())) file_path = BASE_DIR + '/report/html_report/' + time_stamp + ".html" test_dir = BASE_DIR + '/test_cases' allure_reports = BASE_DIR + '/report/allure_reports' allure_report = BASE_DIR + '/report/allure_report' pytest.main([ test_dir, '-v', '-s', '--html=' + file_path, '--alluredir=' + allure_reports, '--reruns', '1', '--reruns-delay', '3' ]) # 本地生成allure报告,jenkins配置allure, 不需要执行命令 # cmd = "allure generate "+allure_reports+" -o "+allure_report + " --clean" # result = self.cmd.execute_result_cmd(cmd) self.email_util.send_email(file_path) self.alert.send_text("ui测试完成, 已发送邮件") self.logger.info("ui测试完成,邮件已发送")
def __init__(self): self.cmd = Command() self.email_util = EmailUtil() self.alert = Alert() self.logger = Logger().get_logger()
def resend_confirmation(): token = current_user.generate_confirmation_token() EmailUtil.send_confirm_email(user=current_user, token=token) flash(_('A new confirmation email has been sent to you by email'), 'info') return redirect(url_for('main.index'))
def handle_row(self, mapped_row, raw_row, row_number): super().handle_row(mapped_row, raw_row, row_number) # Is this row an artifact of some kind of App or other synthetic data? if self.should_ignore_row(raw_row): self.logger.warning("Synthetic row. Ignoring. (row: %s)", raw_row) return False # TODO: special optimizations for the wise-crackers... # (1) fname = "ploni almoni", lname = <empty> # (2) fname = <empty>, lname = "ploni almoni" # (3) fname = "ploni almoni", lname = "*****@*****.**" # Sanity check to make sure row is with values if mapped_row is None or mapped_row['email1'] is None: self.logger.error("Something went awry... email attribute is None. Aborting") raise Exception("Something went awry during parsing... email attribute is None. Aborting") ed = [] emails = set() for i in [1, 2, 3]: attr = 'email%d' % i if attr in mapped_row and mapped_row[attr].strip() != '': emails.add(mapped_row[attr].strip()) verified_emails = [e for e in list(emails) if EmailUtil.is_valid(e)] best_email = EmailUtil.get_preferred_email_from_list(verified_emails) if best_email is None: if emails is None or len(emails) == 0: reason = "No emails detected" elif len(verified_emails) == 0: reason = "No verified emails - %s" % emails else: reason = "%s" % emails self.logger.warning("Row %d: %s %s: Cannot set key email. %s. Ignoring.", row_number, mapped_row['first_name'], mapped_row['last_name'], reason) return False key_email = EmailUtil.email_as_key(best_email) ed.append(EnrichmentData(P.EMAIL, key_email, 'override')) key = {P.EMAIL: key_email} error = None fname = AcureRateUtils.remove_parenthesized_content(mapped_row['first_name'].strip()) lname = AcureRateUtils.remove_parenthesized_content(mapped_row['last_name'].strip()) if '?' in fname or '?' in lname: self.logger.warning("Row %d - found suspicious name - fname: %s, lname: %s ('?' in name). Replacing and continuing.", row_number, mapped_row['first_name'], mapped_row['last_name']) fname = fname.replace('?', '').strip() lname = lname.replace('?', '').strip() if not AcureRateUtils.valid_name(fname) or not AcureRateUtils.valid_name(lname): self.logger.warning("Row %d: non-alphanumeric characters in name - fname: %s, lname: %s. Continuing.", row_number, mapped_row['first_name'], mapped_row['last_name']) # Handle cases where contact full English name is in FIRST_NAME field and full name in Hebrew in LAST_NAME if len(fname.split()) == 2 and lname == '': lname = fname.split()[1] fname = fname.split()[0] elif len(lname.split()) == 2 and fname == '': fname = lname.split()[0] lname = lname.split()[1] if fname == "" or lname == "": error = "Row %d: empty name after cleaning - fname: %s, lname: %s. Ignoring." % (row_number, mapped_row['first_name'], mapped_row['last_name']) elif '&' in fname or '&' in lname: error = "Row %d: '&' in name after cleaning - fname: %s, lname: %s. Ignoring." % (row_number, mapped_row['first_name'], mapped_row['last_name']) elif '@' in fname or '@' in lname: error = "Row %d: '@' in name after cleaning - fname: %s, lname: %s. Ignoring." % (row_number, mapped_row['first_name'], mapped_row['last_name']) elif len(fname) == 1 and len(lname) == 1: error = "Row %d: suspicious name - fname: %s, lname: %s (too short...) Ignoring." % (row_number, mapped_row['first_name'], mapped_row['last_name']) if error: self.logger.warning(error) return False if len(fname) <= 2 or len(lname) <= 2: self.logger.warning("Row %d: suspicious name - fname: %s, lname: %s (too short...) Continuing.", row_number, mapped_row['first_name'], mapped_row['last_name']) if len(fname.split()) > 1 or len(lname.split()) > 1: self.logger.warning("Row %d: suspicious name - fname: %s, lname: %s (space in fname/lname) Continuing.", row_number, mapped_row['first_name'], mapped_row['last_name']) ed.append(EnrichmentData(P.FIRST_NAME, fname.title(), 'override')) ed.append(EnrichmentData(P.LAST_NAME, lname.title(), 'override')) if mapped_row['middle_name'].strip() != "": ed.append(EnrichmentData(P.MIDDLE_NAME, mapped_row['middle_name'].strip(), 'override')) if mapped_row['prefix'].strip() != "": ed.append(EnrichmentData(P.PREFIX, mapped_row['prefix'].strip(), 'override')) if mapped_row['suffix'].strip() != "": ed.append(EnrichmentData(P.SUFFIX, mapped_row['suffix'].strip(), 'override')) # Handle email attributes (even if some are invalid emails - may lead to needed info in later stages) for i in [1, 2, 3]: if ("email%d" % i) in mapped_row and mapped_row["email%d" % i].strip() != "": ed.append(EnrichmentData(P.EMAILS, mapped_row["email%d" % i].strip(), 'add')) # Handle phone attributes for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]: if ("phone%d" % i) in mapped_row and mapped_row["phone%d" % i].strip() != "": ed.append(EnrichmentData(P.PHONES, mapped_row["phone%d" % i].strip(), 'add')) # TODO: handle cases where more than one org/title is mentioned # TODO: write code better... (dict2dict... ?) org = mapped_row.get('job_name1', None) title = mapped_row.get('job_title1', None) if org is not None and org.strip() != "" and title is not None and title.strip() != "": ed.append(EnrichmentData(P.JOBS, {'job_name': org, 'job_title': title}, 'add')) elif org is not None and org.strip() != "" and title is None: ed.append(EnrichmentData(P.JOBS, {'job_name': org}, 'add')) elif org is None and title is not None and title.strip() != "": ed.append(EnrichmentData(P.JOBS, {'job_title': title}, 'add')) # Is there a DOB field? Convert it to python timestamp if P.DOB in mapped_row and mapped_row[P.DOB] != '': ed.append(EnrichmentData(P.DOB, AcureRateUtils.normalized_dob(mapped_row[P.DOB]), 'add')) # Is there a direct manager marked? if P.DIRECT_MANAGER in mapped_row and mapped_row[P.DIRECT_MANAGER] != '': ed.append(EnrichmentData(P.DIRECT_MANAGER, mapped_row[P.DIRECT_MANAGER], 'add')) if P.WEBSITE in mapped_row and mapped_row[P.WEBSITE] != '': ed.append(EnrichmentData(P.WEBSITE, mapped_row[P.WEBSITE], 'add')) # Anything worthwhile in the notes? if 'notes' in mapped_row and mapped_row['notes'].strip() != '': #self.logger.info('Row %d - contact %s %s got notes - anything interesting here? Notes: %s', row_number, fname, lname, mapped_row['notes']) self.logger.info('Row %d: contact %s %s got notes - anything interesting here?', row_number, fname, lname) # Anything worthwhile in the notes? if 'categories' in mapped_row and mapped_row['categories'].strip() != '': categories = mapped_row['categories'].lower().split(";") # TODO: temp code below. Remove. if 'friends' in categories or 'friend' in categories or 'sayarut' in categories or 'hofen' in categories: self.logger.warning('Contact %s %s filtered out because of irrelevant category (categories: %s)', fname, lname, mapped_row['categories']) return False # Mark the source these contacts came from: ed.append(EnrichmentData(P.ATTRIBUTION_ID, self.attribution_id, 'override')) ed.append(EnrichmentData(P.ATTRIBUTION_NAME, self.attribution_name, 'override')) if not self.test_import: self.logger.info('Row %d: key_email: %s. Sending to enrichment...', row_number, key_email) source = EnrichmentSource(source_type=self.source, source_key='%s %s' % (self.attribution_id, best_email.lower())) behavior = EnrichmentBehavior(create_new=True, providers=self.providers) self.es.enrich_person(enrichment_key=key, enrichment_data=ed, enrichment_source=source, enrichment_behavior=behavior) return True
def send_email_task(receiver, title, content, did, username, diary_title): EmailUtil(SmtpConfig).send_reply_mail(receiver, title, content, did, username, diary_title)
def send_error_email_task(title, error_log): EmailUtil(SmtpConfig).send_error_email(title, error_log)
def enrich_company(self): company_name = self.enriched_entity.deduced.get(C.NAME, None) if company_name is None: self.logger.warning('Unable to enrich company. No name detected in entity: %s', self.enriched_entity) return # If there's a permalink, use it, otherwise try creating one if C.CRUNCHBASE_URL in self.enriched_entity.deduced: url = self.enriched_entity.deduced[C.CRUNCHBASE_URL] if url.find('/organization') == 0: url = 'https://www.crunchbase.com' + url permalink = AcureRateUtils.get_url_last_path_element(url) else: permalink = self.enriched_entity.deduced.get(C.CRUNCHBASE_PERMALINK, CrunchBaseEngager.formalize_permalink(company_name)) url = 'https://www.crunchbase.com/organization/%s#/entity' % permalink #driver = webdriver.Firefox() driver = webdriver.Chrome(r'C:\Python353\browser_drivers\chromedriver') driver.implicitly_wait(20) # seconds try: # Activate the driver driver.get(url) # If we got to here, keep the permalink self.set_data(C.CRUNCHBASE_PERMALINK, permalink) # Get company name try: name = driver.find_element_by_id('profile_header_heading').text self.set_data(C.NAME, name) driver.implicitly_wait(2) # seconds except: # TODO: there should be a smarter way to understand we got 404... s = "Failed to enrich %s. Unable to locate name entity in page - %s - something went awry... dumping this crawl." % (company_name, url) raise EngagementException(s) # Get company logo try: content = driver.find_element_by_class_name('logo-links-container') logo_url = content.find_element_by_css_selector("div > img").get_attribute("src") self.add_data(C.LOGOS, {C.LOGO_URL: logo_url, C.LOGO_SOURCE: 'crunchbase'}) except: pass # Get overview stats (acquisitions, total funds, etc.) try: stats = driver.find_element_by_class_name('overview-stats').text if stats.strip() != "": self.set_data(C.STATS, stats) stats_lower = stats.replace('\n', ' ').lower() if 'acquired by' in stats_lower and stats_lower.find(' on ') > 0: acquiring_company = stats[stats_lower.find('acquired by')+12:stats_lower.find(' on ')] self.set_data(C.ACQUIRED_BY, acquiring_company) #tokens = stats.split('\n') #self.set_data(C.ACQUIRED_BY, tokens[2]) except: pass # Get headquarters try: content = driver.find_element_by_xpath('//dt[text()="Headquarters:"]') headquarters = content.find_element_by_xpath("following-sibling::*[1]").text self.set_data(C.HEADQUARTERS, headquarters) except: pass # Get description try: content = driver.find_element_by_xpath('//dt[text()="Description:"]') description = content.find_element_by_xpath("following-sibling::*[1]").text self.set_data(C.DESCRIPTION, description) except: pass # Get founders try: founders = [] content = driver.find_element_by_xpath('//dt[text()="Founders:"]').find_element_by_xpath("following-sibling::*[1]") founders_elements = content.find_elements_by_css_selector('a') for f in founders_elements: name = f.get_attribute("data-name") permalink = f.get_attribute("data-permalink") image = f.get_attribute("data-image") founders.append(name) #founders.append((name, permalink, image)) self.set_data(C.FOUNDERS, founders) except Exception as e: print(e) # Get categories try: content = driver.find_element_by_xpath('//dt[text()="Categories:"]') categories = content.find_element_by_xpath("following-sibling::*[1]").text for c in categories.split(","): self.add_data(C.CATEGORIES, c) except: pass # Get web-site try: content = driver.find_element_by_xpath('//dt[text()="Website:"]').find_element_by_xpath("following-sibling::*[1]") website_url = content.find_element_by_css_selector('a').get_attribute("href") self.set_data(C.WEBSITE, website_url) except: pass # Get socials try: content = driver.find_element_by_xpath('//dt[text()="Social: "]').find_element_by_xpath("following-sibling::*[1]") social_links_elems = content.find_elements_by_tag_name('a') for e in social_links_elems: social_type = e.get_attribute('data-icons') # "facebook", "twitter", etc. social_link = e.get_attribute('href') if social_type == 'facebook': self.set_data(C.FACEBOOK_URL, social_link) elif social_type == 'twitter': self.set_data(C.TWITTER_URL, social_link) except Exception as e: print(e) # Get founding year try: content = driver.find_element_by_xpath('//dt[text()="Founded:"]') founding_year = content.find_element_by_xpath("following-sibling::*[1]").text self.set_data(C.FOUNDING_YEAR, founding_year) except: pass # Get contact email - for emails-domain info try: content = driver.find_element_by_xpath('//dt[text()="Contact:"]') contact_info = content.find_element_by_xpath("following-sibling::*[1]").text tokens = contact_info.split(' ') # contact info may be structured: [email protected] | Telephone email_domain = EmailUtil.get_email_domain_part(tokens[0]) if email_domain and len(email_domain) > 0: self.add_data(C.EMAIL_DOMAINS, email_domain) except: pass # Get aliases try: content = driver.find_element_by_xpath('//dt[text()="Aliases:"]') aliases = content.find_element_by_xpath("following-sibling::*[1]").text for a in aliases.split(", "): self.add_data(C.ALIASES, a) except: pass # Get company type try: content = driver.find_element_by_xpath('//dt[text()="Type:"]') type_str = content.find_element_by_xpath("following-sibling::*[1]").text self.set_data(C.INVESTMENT_COMPANY_TYPE, type_str) except: pass # Get sectors (in case it's investor company) try: content = driver.find_element_by_xpath('//dt[text()="Sectors:"]') sectors_str = content.find_element_by_xpath("following-sibling::*[1]").text for c in sectors_str.split(", "): self.add_data(C.CATEGORIES, c) except: pass # Get Investment Size (in case it's investor company) try: content = driver.find_element_by_xpath('//dt[text()="Investment Size:"]') investments_size_str = content.find_element_by_xpath("following-sibling::*[1]").text self.set_data(C.INVESTMENTS_RANGE, investments_size_str.replace(" ","")) except: pass # Get investments regions (in case it's investor company) try: content = driver.find_element_by_xpath('//dt[text()="Regions:"]') investments_regions_str = content.find_element_by_xpath("following-sibling::*[1]").text for r in investments_regions_str.split(", "): self.add_data(C.INVESTMENT_REGIONS, r) except: pass # Get employees range try: content = driver.find_element_by_xpath('//dt[text()="Employees:"]') employees_range_str = content.find_element_by_xpath("following-sibling::*[1]").text i = employees_range_str.find('None found') if i < 0: self.set_data(C.EMPLOYEES_RANGE, employees_range_str.replace(" ", "")) elif i > 0: self.set_data(C.EMPLOYEES_RANGE, employees_range_str.replace(" ", "")[:employees_range_str.find("|")-1]) except: pass # Get investors try: investors = [] investors_tables = driver.find_elements_by_css_selector(".table.investors") if len(investors_tables) > 0: investors_rows_elements = investors_tables[0].find_elements_by_tag_name("tbody") for investor_element in investors_rows_elements: # skip the header row of the table rows = investor_element.find_elements_by_tag_name("tr") for row in rows: cols = row.find_elements_by_tag_name("td") investor_permalink = '' if len(cols) == 3: investor_name = cols[0].text round = cols[1].text partner = cols[2].text investor_permalink = cols[0].find_element_by_class_name("follow_card").get_attribute('data-permalink') elif len(cols) == 2: round = cols[0].text partner = cols[1].text if "/organization" in investor_permalink: investor_type = "organization" else: investor_type = "person" if 'Seed' in round or 'Angel' in round: str = "%s / %s" % (partner, round) investors.append((investor_name, investor_type, str)) else: str = "%s / %s" % (partner, round) investors.append((investor_name, investor_type, str)) if len(investors) > 0: self.set_data(C.INVESTORS, investors) except Exception as e: print(e) # TODO: get Acquisitions # Get current team current_team = [] try: people_table = driver.find_elements_by_class_name('people') if len(people_table) > 0: # TODO: get the person title - we don't want developers here... people_rows_element = people_table[1].find_elements_by_css_selector("li") for person in people_rows_element: name_element = person.find_element_by_css_selector("h4 a") name = name_element.get_attribute('data-name') permalink = name_element.get_attribute('data-permalink') title_element = person.find_element_by_css_selector("h5") title = title_element.text image = person.find_element_by_css_selector("span a img").get_attribute("src") current_team.append(name) #current_team.append((name, permalink, title, image)) except Exception as e: print(e) # Get past team try: people_table = driver.find_elements_by_class_name('past_people') if len(people_table) > 0: # TODO: get the person title - we don't want developers here... people_rows_element = people_table[0].find_elements_by_css_selector("li") for person in people_rows_element: name_element = person.find_element_by_css_selector("h4 a") name = name_element.get_attribute('data-name') #permalink = name_element.get_attribute('data-permalink') #title_element = person.find_element_by_css_selector("h5") #title = title_element.text #image = person.find_element_by_css_selector("span a img").get_attribute("src") current_team.append(name) #current_team.append((name, permalink, title, image)) except Exception as e: print(e) # Store past & current team if len(current_team) > 0: self.set_data(C.TEAM, current_team) # Get board members and advisors try: advisors = [] advisors_table = driver.find_elements_by_css_selector('.base.no-data.advisors') if len(advisors_table) == 0: advisors_table = driver.find_elements_by_css_selector('.base.advisors') if len(advisors_table) > 0: advisors_rows_elements = advisors_table[0].find_elements_by_css_selector("h4 a") for advisor_element in advisors_rows_elements: name = advisor_element.get_attribute('data-name') permalink = advisor_element.get_attribute('data-permalink') # TODO: check that investors is person and not organization advisors.append(name) #advisors.append((name, permalink)) if len(advisors) > 0: self.set_data(C.ADVISORS, advisors) except Exception as e: print(e) except Exception as e: raise e driver.close() return [C.NAME]