how to make text clickable in python - python

How to make text clickable ?
class ComplainceServer():
def __init__(self, jira_server, username, password, encoding='utf-8'):
if jira_server is None:
error('No server provided.')
#print(jira_server)
self.jira_server = jira_server
self.username = username
self.password = password
self.encoding = encoding
def checkComplaince(self, appid, toAddress):
query = "/rest/api/2/search?jql=issuetype = \"Application Security\" AND \"Prod Due Date\" < now()
request = self._createRequest()
response = request.get(query, contentType='application/json')
# Parse result
if response.status == 200 and action == "warn":
data = Json.loads(response.response)
print "#### Issues found"
issues = {}
msg = "WARNING: The below tickets are non-complaint in fortify, please fix them or raise exception.\n"
issue1 = data['issues'][0]['key']
for item in data['issues']:
issue = item['key']
issues[issue] = item['fields']['summary']
print u"* {0} - {1}".format(self._link(issue), item['fields']['summary'])
print "\n"
data = u" {0} - {1}".format(self._link(issue), item['fields']['summary'])
msg += '\n'+ data
SOCKET_TIMEOUT = 30000 # 30s
email = SimpleEmail()
email.setHostName('smtp.com')
email.setSmtpPort(25)
email.setSocketConnectionTimeout(SOCKET_TIMEOUT);
email.setSocketTimeout(SOCKET_TIMEOUT);
email.setFrom('R#group.com')
for toAddress in toAddress.split(','):
email.addTo(toAddress)
email.setSubject('complaince report')
email.addHeader('X-Priority', '1')
email.setMsg(str(msg))
email.send()
def _createRequest(self):
return HttpRequest(self.jira_server, self.username, self.password)
def _link(self, issue):
return '[{0}]({1}/browse/{0})'.format(issue, self.jira_server['url'])
This is the calling function. APPid and toAddress will be passed in from different UI.
from Complaince import ComplainceServer
jira = ComplainceServer(jiraServer, username, password)
issues = jira.checkComplaince(appid, toAddress)
I want issueid to be an embedded link.
currently the email sends as below:
MT-4353(https://check.com/login/browse/MT-4353) - Site Sc: DM isg_cq5
but i want [MT-4353] as hyperlink to the URL https://check.com/login/browse/MT-4353

Firstly, you need to encode your email as html. I'm not familiar with the library you are using so I cannot give an example of this.
I have replaced a snippet of your code with html syntax just to illustrate the point that you are meant to use html syntax to have clickable links in an email.
msg = "<p>WARNING: The below tickets are non-compliant in fortify, please fix them or raise exception.</p>"
issue1 = data['issues'][0]['key']
for item in data['issues']:
issue = item['key']
issues[issue] = item['fields']['summary']
data = u"<a href='{0}'>{1}</a>".format(self._link(issue), item['fields']['summary'])
msg += '<br />'+ data
In future, please ask your questions carefully as your title does not question does not indicate what you are actually meaning. You also have spelling mistakes: Compliant
Oh, I missed the point of self._link(issue) not returning the correct link. It returns MT-4353(https://check.com/login/browse/MT-4353) so you are going to need to extract the link part between the brackets. I suggest a regular expression.

Related

This code won't extract links from Selenium, but it also doesn't give me any errors, what did I do wrong?

Everything in the first piece of code works flawlessly, but the second one does nothing, even though the code is being registered. What I eventually want to happen is for the code to find the links of the first 6 Instagram posts, and store their metrics (for now just the views). But I want to do this across different accounts. Meaning different link directories. What this code is supposed to as of now is to get the "href" attribute of the "v1Nh3 kIKUG _bz0w" class and store it in a list. I've referenced the HTML for a better idea of what we're dealing with here. Help!!
from selenium import webdriver
from time import sleep
import random
import re
#bot detect evasion
waiting_time = [4,4,8.2,4,6,13,7.2,3.4,6.5,9]
number = 3 #random.choice(waiting_time)
bigger_number = 4000000
class seeder_gram():
def __init__(self, username, phone, email, password):
self.username = username
self.phone = phone
self.email = email
self.password = password
self.driver = webdriver.Chrome("/Users/apple/Downloads/chromedriver")
self.driver.get('https://instagram.com')
sleep(number)
#username insert
username_form = self.driver.find_element_by_xpath('/html/body/div[1]/section/main/article/div[2]/div[1]/div/form/div/div[1]/div/label/input')
username_form.clear()
username_form.send_keys("nothingtoseehere")
#password insert
password_form = self.driver.find_element_by_xpath('/html/body/div[1]/section/main/article/div[2]/div[1]/div/form/div/div[2]/div/label/input')
password_form.clear()
password_form.send_keys("nothingtoseehere")
#clicks button
button_click = self.driver.find_element_by_xpath('/html/body/div[1]/section/main/article/div[2]/div[1]/div/form/div/div[3]/button')
button_click.click()
sleep(number)
#close noti bar
try:
noti_pop_up = self.driver.find_element_by_xpath('/html/body/div[4]/div/div/div/div[3]/button[2]')
noti_pop_up.click()
except:
pass
#list of targets
account_list = ["nothingtoseehere", "nothingtoseehere", "nothingtoseehere", "nothingtoseehere", "nothingtoseehere", "nothingtoseehere"]
account_picker = random.choice(account_list)
#searches for target
self.driver.get('https://instagram.com/' + account_picker + '/')
sleep(number)
#post list
post_id_finder = self.driver.find_elements_by_class_name("v1Nh3 kIKUG _bz0w")
list_of_links = []
def get_href(post_id_finder):
for post in post_id_finder:
link = post_id_finder.get_attribute('href')
link.append(list_of_links)
print(list_of_links)
get_href(post_id_finder)
"""
#gives unique post directory
#eventually this will be a list that appends links depending on post
post_id = "/p/CLWlksPHsvN/"
#searches for the first grid
grid_search = self.driver.find_element_by_xpath('//*[#id="react-root"]/section/main/div/div[4]/article/div[1]/div/div[1]')
#goes to post
post_viewer = self.driver.get('https://www.instagram.com' + post_id)
#checks view
video_views = self.driver.find_element_by_xpath('/html/body/div[1]/section/main/div/div[1]/article/div[3]/section[2]/div/span')
views = re.findall(r'\d', video_views.text)
print(views)
#combines view value
post_index = 1
while post_index != 6:
#finds videos that show views
#what if the video isnt based on views??
#logs views in list
#goes back one page
#moves on to next post
post_index += 1
"""
#back up serch feature in case first doesn't work, needs more work added though to make functional
"""
search_up = self.driver.find_element_by_xpath('/html/body/div[1]/section/nav/div[2]/div/div/div[2]/input')
search_up.clear()
search_up.send_keys(account_picker)
"""
sleep(bigger_number)
#registered users
user1 = seeder_gram("nothingtoseehere", "nothingtoseehere", "nothingtoseehere", "nothingtoseeheres")
user2 = seeder_gram("nothingtoseehere", "nothingtoseehere", "nothingtoseehere", "nothingtoseehere")
seeder_gram()
This is the code I'm having trouble with:
#post list
post_id_finder = self.driver.find_elements_by_class_name("v1Nh3 kIKUG _bz0w")
list_of_links = []
def get_href(post_id_finder):
for post in post_id_finder:
link = post_id_finder.get_attribute('href')
link.append(list_of_links)
print(list_of_links)
get_href(post_id_finder)
Here is what the HTML looks like, if there's a better way to do this:
You can't use multiple class names in find_element_by_class name, you're best off using something like find by css selector.

Try/Except to Check String and perform the function in Python and Twilio

I am trying to parse through the body message then return the values that the user requests. I couldn't figure out how to store a 5 character zipcode so I decided to use a try and except within the function. So essentially, I want the user to send the text, such as "SenEmail", then be prompted for their zipcode and return the the data (I currently only having it return the API call url for simplicity). However, its not working properly, I keep getting an error that my indentation is off or invalid syntax on the 'body == 'SenWeb': " and when it does work, it returns all 3 API call links, and not just the one associated with it. So SenPhone will return(Sending 3 texts of all the info rather than just 1), SenPhone, SenWeb and SenEmail rather than just SenPhone. I am fairly new to python, as you can probably tell. Thank you for your consideration.
import urllib.request as urlr
import urllib.parse as url
import urllib.error as urle
import json
import os
from flask import Flask, request, redirect
from twilio import twiml
from twilio.twiml.messaging_response import MessagingResponse
app = Flask(__name__)
#app.route('/sms', methods=['GET', 'POST'])
def sms_reply():
r = MessagingResponse()
body = request.values.get('Body', None)
if body == 'SenPhone':
r.message("Welcome to PollText! Reply with Zip for Senators Phone Num's.")
try:
if len(body) == 5:
url = 'https://www.googleapis.com/civicinfo/v2/representatives?address='
z_c = str(body)
key = '&key=xxxxxxxxxxxxxxxxxxx'
serviceurl = url+z_c+key
address = serviceurl
r.message(str(serviceurl + "Phone"))
else:
r.message("SenPhone, SenWeb, SenEmail")
elif body == 'SenWeb':
r.message("Welcome to PollText! Reply with Zip for Senators Website.")
try:
if len(body) == 5:
url = 'https://www.googleapis.com/civicinfo/v2/representatives?address='
z_c = str(body)
key = '&key=xxxxxxxxxxxxxxxxxxx'
serviceurl = url+z_c+key
address = serviceurl
r.message(str(serviceurl + "Website"))
else:
r.message("SenPhone, SenWeb, SenEmail")
elif body == "SenEmail":
r.message("Welcome to PollText! Reply with Zip for Senators Email's.")
try:
if len(body) == 5:
url = 'https://www.googleapis.com/civicinfo/v2/representatives?address='
z_c = str(body)
key = '&key=xxxxxxxxxxxxxxxxxxx'
serviceurl = url+z_c+key
address = serviceurl
r.message(str(serviceurl + "Email"))
except:
r.message('Sorry, that was not a valid input message.')
return str(r)
if __name__ == "__main__":
app.run(debug=True)
Twilio developer evangelist here.
I popped your code into a Python validator and it also told me that the elif was wrong.
However, I then looked up the file a bit and noticed that under your if, it looked like this:
if body == 'SenPhone':
r.message("Welcome to PollText! Reply with Zip for Senators Phone Num's.")
try:
if len(body) == 5:
So, the issue is that the try is outdented and has ended the conditional. I think if you indent that, then your syntax error will go away and you can continue to debug the rest from there.

Python with Sqlite 3, how to extract only text, without 'u?

I have the following code:
password_master = str(self.master_password.text())
username = str(self.comboBox.currentText())
result = c.execute("SELECT * FROM register_table WHERE MASTER = '"+password_master+"' AND USERNAME = '"+username+"'")
if (len(result.fetchall()) > 0):
print("user found")
password_check = c.execute("SELECT PASSWORD FROM register_table WHERE USERNAME = '"+username+"' AND MASTER = '"+password_master+"'").fetchall()
password = str(password_check)
login(username, password)
From the "password_check" query I would like to extract only the text, because I need to pass variable "password" to "login" function.
I tried everything but I always receive the following output:
[(u'#-passwordtest-#',)]
Is there a way to extract simply
passwordtest
Many thanks in advance!!!
First off, I'll start with the standard SQL Injection warning. Granted, this doesn't look like it's web facing, but still. You should be using bind variables.
Secondly, your query will return an array of values, so you're trying to run the str() function on an array that contains strings. I would replace the lines:
password_check = c.execute("SELECT PASSWORD FROM register_table WHERE USERNAME = '"+username+"' AND MASTER = '"+password_master+"'").fetchall()
password = str(password_check)
with:
results = c.execute("SELECT PASSWORD FROM register_table WHERE USERNAME = '"+username+"' AND MASTER = '"+password_master+"'").fetchone()
password = results[0]

Results not showing after search term entered from keyboard

I am learning to develop an addon for Kodi and need to implement a search functionality. I found some resources online to get user input from keyboard and then calling an API with the search term to fetch results. The API is being requested fine but the results are not being shown through ListItems. Below is my code
_url = sys.argv[0]
_handle = int(sys.argv[1])
def get_url(**kwargs):
return '{0}?{1}'.format(_url, urlencode(kwargs))
def display_main_menu():
list_item = xbmcgui.ListItem(label="Search")
url = get_url(action='search')
xbmcplugin.addDirectoryItem(_handle, url, list_item)
def perform_search(search_term):
link = "api_url_here" + search_term
r = requests.get(link)
resp = json.loads(r.text)
for result in resp:
list_item = xbmcgui.ListItem(label=result["name"])
list_item.setArt({'thumb': result["img"], 'icon' : result["img"], 'fanart' : result["img"]})
url = '' #blank url for testing
is_folder = True
xbmcplugin.addDirectoryItem(_handle, url, list_item, is_folder)
xbmcplugin.endOfDirectory(_handle)
def search():
keyb = xbmc.Keyboard('',"Search for Videos", False)
keyb.setDefault('')
keyb.doModal()
if (keyb.isConfirmed() and len(keyb.getText()) > 0):
perform_search(keyb.getText())
def router(paramstring):
params = dict(parse_qsl(paramstring))
if params:
if params['action'] == 'search':
search()
else:
raise ValueError('Invalid paramstring: {0}!'.format(paramstring))
else:
display_main_menu()
if __name__ == '__main__':
router(sys.argv[2][1:])
When I select Search and then type my word to search the keyboard is dismissed but nothing happens. The same menu is being displayed and new ListItems from the perform_search function are not being displayed. Also, there is no error. Please help.
Add some logging, the interesting part will be if you actually hit the for. So add some xbmc.log('hit') or even log your values.
If you want a full blown logging check this example https://github.com/xbmc/generator-kodi-addon/blob/master/generators/app/templates/resources/lib/kodilogging.py

Why is one of my functions running twice?

The function search_for_song(pbody) is running twice, i can't figure out why.
would like some help, just started learning python a few days ago.
Here's the full code:
#a bot that replies with youtube songs that were mentioned in the comments
import traceback
import praw
import time
import sqlite3
import requests
from lxml import html
import socket
import errno
import re
import urllib
from bs4 import BeautifulSoup
import sys
import urllib2
'''USER CONFIGURATION'''
APP_ID = ""
APP_SECRET = ""
APP_URI = ""
APP_REFRESH = ""
# https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
USERAGENT = "Python automatic youtube linkerbot"
# This is a short description of what the bot does.
# For example "Python automatic replybot v2.0 (by /u/GoldenSights)"
SUBREDDIT = "kqly"
# This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
DO_SUBMISSIONS = False
DO_COMMENTS = True
# Look for submissions, comments, or both.
KEYWORDS = ["linksong"]
# These are the words you are looking for
KEYAUTHORS = []
# These are the names of the authors you are looking for
# The bot will only reply to authors on this list
# Keep it empty to allow anybody.
#REPLYSTRING = "**Hi, I'm a bot.**"
# This is the word you want to put in reply
MAXPOSTS = 100
# This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
WAIT = 30
# This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
CLEANCYCLES = 10
# After this many cycles, the bot will clean its database
# Keeping only the latest (2*MAXPOSTS) items
'''All done!'''
try:
import bot
USERAGENT = bot.aG
except ImportError:
pass
print('Opening SQL Database')
sql = sqlite3.connect('sql.db')
cur = sql.cursor()
cur.execute('CREATE TABLE IF NOT EXISTS oldposts(id TEXT)')
print('Logging in...')
r = praw.Reddit(USERAGENT)
r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
r.refresh_access_information(APP_REFRESH)
def replybot():
print('Searching %s.' % SUBREDDIT)
subreddit = r.get_subreddit(SUBREDDIT)
posts = []
if DO_SUBMISSIONS:
posts += list(subreddit.get_new(limit=MAXPOSTS))
if DO_COMMENTS:
posts += list(subreddit.get_comments(limit=MAXPOSTS))
posts.reverse()
for post in posts:
#print ("Searching for another the next comment")
# Anything that needs to happen every loop goes here.
pid = post.id
try:
pauthor = post.author.name
except AttributeError:
# Author is deleted. We don't care about this post.
continue
if pauthor.lower() == r.user.name.lower():
# Don't reply to yourself, robot!
print('Will not reply to myself.')
continue
if KEYAUTHORS != [] and all(auth.lower() != pauthor for auth in KEYAUTHORS):
# This post was not made by a keyauthor
continue
cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
if cur.fetchone():
# Post is already in the database
continue
if isinstance(post, praw.objects.Comment):
pbody = post.body
else:
pbody = '%s %s' % (post.title, post.selftext)
pbody = pbody.lower()
if not any(key.lower() in pbody for key in KEYWORDS):
# Does not contain our keyword
continue
cur.execute('INSERT INTO oldposts VALUES(?)', [pid])
sql.commit()
print('Replying to %s by %s' % (pid, pauthor))
try:
if search_for_song(pbody):
# pbody=pbody[8:]
# pbody=pbody.replace("\n", "")
temp=pbody[8:].lstrip()
post.reply("[**"+temp+"**]("+search_for_song(pbody)+") \n ---- \n ^^This ^^is ^^an ^^automated ^^message ^^by ^^a ^^bot, ^^if ^^you ^^found ^^any ^^bug ^^and/or ^^willing ^^to ^^contact ^^me. [**^^Press ^^here**](https://www.reddit.com/message/compose?to=itailitai)")
except praw.errors.Forbidden:
print('403 FORBIDDEN - is the bot banned from %s?' % post.subreddit.display_name)
def search_for_song(pbody):
#print("in search_for_song")
song=pbody
if len(song)>8:
song=song[8:]
if song.isspace()==True or song=='':
return False
else:
print("Search if %s exists in the database" % song )
#HEADERS = {'User-Agent': 'Song checker - check if songs exists by searching this website, part of a bot for reddit'}
author, song_name = song_string_generator(song)
url = 'http://www.songlyrics.com/'+author+'/'+song_name+'-lyrics/'
print url
#page = requests.get(url, HEADERS)
check=1
while check==1:
try:
headers = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; rv:40.0) Gecko/20100101 Firefox/40.0' }
req = urllib2.Request(url, None, headers)
page= urllib2.urlopen(req)
check=2
except socket.error as error:
pass
except Exception:
print('An error occured while tryinc to verify song existence')
return False
soup = BeautifulSoup(page.read(), "lxml")
if "Please check the spelling and try again" not in soup.get_text():
print ("Song was found in the database!")
result=first_youtube(song)
return result
else:
print ("Song was not found in the database!")
return False
def song_string_generator(song):
#print("in song_string_generator")
song=song
author,song_name= '',''
try:
if "-" in song:
l=song.split('-', 1 )
print ("2 ",l)
author=l[0]
song_name=l[1]
elif "by" in song:
l=song.split('by', 1 )
print ("2 ",l)
author=l[1]
song_name=l[0]
song_name=" ".join(song_name.split())
author=" ".join(author.split())
print (author,song_name)
if author == 'guns and roses':
author="guns n' roses"
song_name=song_name.replace("\n", "")
author=author.replace("\n", "")
author=author.replace(" ", "-")
song_name=song_name.replace(" ", "-")
author=author.replace("'", "-")
song_name=song_name.replace("'", "-")
song_name=song_name.rstrip()
song_name=" ".join(song_name.split())
return author, song_name
except:
print ("No song was mentioned in the comment!")
return False
def first_youtube(textToSearch):
reload(sys)
sys.setdefaultencoding('UTF-8')
query_string = textToSearch
try:
html_content = urllib.urlopen("http://www.youtube.com/results?search_query=" + query_string)
search_results = re.findall(r'href=\"\/watch\?v=(.{11})', html_content.read().decode())
result="http://www.youtube.com/watch?v=" + search_results[0]
return result
except IOError:
print ("IOError Occured while contacting Youtube!")
except Exception:
print ("A non IOError Occured while contacting Youtube!")
return False
cycles = 0
while True:
try:
replybot()
cycles += 1
except Exception as e:
traceback.print_exc()
if cycles >= CLEANCYCLES:
print('Cleaning database')
cur.execute('DELETE FROM oldposts WHERE id NOT IN (SELECT id FROM oldposts ORDER BY id DESC LIMIT ?)', [MAXPOSTS * 2])
sql.commit()
cycles = 0
print('Running again in %d seconds \n' % WAIT)
time.sleep(WAIT)
This is the output I'm getting:
Opening SQL Database
Logging in...
Searching kqly.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Will not reply to myself.
Replying to d0kwcrs by itailitai
Search if guns and roses - paradise city exists in the database
('2 ', [u' guns and roses ', u' paradise city'])
(u'guns and roses', u'paradise city')
http://www.songlyrics.com/guns-n--roses/paradise-city-lyrics/
Song was found in the database!
Search if guns and roses - paradise city exists in the database
('2 ', [u' guns and roses ', u' paradise city'])
(u'guns and roses', u'paradise city')
http://www.songlyrics.com/guns-n--roses/paradise-city-lyrics/
Song was found in the database!
Running again in 30 seconds
it's a bot for reddit that replies with the youtube video of a song that was mentioned in the comments, if anyone wants to know.
With a cursory reading of your code you have
if search_for_song(pbody):
# do stuff..
post.reply("[**"+temp+"**]("+search_for_song(pbody)+") \n ---- \n ^^This ^^is ^^an ^^automated ^^message ^^by ^^a ^^bot, ^^if ^^you ^^found ^^any ^^bug ^^and/or ^^willing ^^to ^^contact ^^me. [**^^Press ^^here**](https://www.reddit.com/message/compose?to=itailitai)")
You call the function in the start of the if and in your post.reply line
RESPONDING TO COMMENTS
If you need to check the results but don't want to call twice simply save the output
res = search_for_song(pbody):
if res:
#...
post.reply(... + res + ...)
I've just quickly searched for the function call search_for_song, I suppose the following piece of code is resulting in 2 function calls.
if search_for_song(pbody):
# pbody=pbody[8:]
# pbody=pbody.replace("\n", "")
temp=pbody[8:].lstrip()
post.reply("[**"+temp+"**]("+search_for_song(pbody)+")
Once at the if statement, and once inside the post.reply statement.

Categories

Resources