tiger1974

Untitled

Sep 16th, 2015
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.04 KB | None | 0 0
  1. ###################
  2. # Script Name: Scrape Bluehost Queues
  3. # Author: Brandon West
  4. # Date created: 11/11/2014
  5. # Date last modified: 11/23/2014
  6. # Autokey Version: 0.71.2
  7. # Description: Quickly query wallboards for queue values
  8. ## to be entered into the L3 Trends Google Doc
  9. # Setup: $ sudo pip install mechanize beautifulsoup4 requests
  10. ###################
  11.  
  12. import re
  13. import requests
  14. import mechanize
  15. import cookielib
  16. from bs4 import BeautifulSoup
  17.  
  18.  
  19. ###### SUPPORTING QUEUE CLASS ######
  20. #Queue:
  21. #   queue_id
  22. #   queue_name
  23. #   queue_type
  24. #       count_customers_in_queue
  25. #       top_wait_time
  26. #       avg_wait_time
  27. #       count_techs_logged_in
  28. #       count_techs_with_customers
  29. #       count_techs_unavailable
  30. #       count_techs_available
  31.  
  32.  
  33. # Create a class for Queue objects to store attributes about each queue.
  34. class Queue:
  35.     'Common class for all queue types'
  36.     def __init__(self, queue_type, queue_id, queue_name, count_customers_in_queue, top_wait_time, avg_wait_time, count_techs_logged_in, count_techs_with_customers, count_techs_unavailable, count_techs_available):
  37.         self.type = queue_type
  38.         self.id = queue_id
  39.         self.name = queue_name
  40.         self.type = queue_type
  41.         self.count_customers_in_queue = count_customers_in_queue
  42.         self.top_wait_time = top_wait_time
  43.         self.avg_wait_time = avg_wait_time
  44.         self.count_techs_logged_in = count_techs_logged_in
  45.         self.count_techs_with_customers = count_techs_with_customers
  46.         self.count_techs_unavailable = count_techs_unavailable
  47.         self.count_techs_available = count_techs_available
  48.  
  49.     def __hash__(self):
  50.         return hash((self.id, self.name))
  51.  
  52.     def displayAll(self):
  53.         print "Queue ID: ", self.id
  54.         print "Queue Name: ", self.name
  55.         print "     Queue Type: ", self.type
  56.         print "     Customers Waiting: ", self.count_customers_in_queue
  57.         print "     Top Wait Time: ", self.top_wait_time
  58.         if self.type == "call":
  59.             print "     Avg. Wait Time: ", self.avg_wait_time
  60.         print "     Techs Logged In: ", self.count_techs_logged_in
  61.         print "     Techs with Customers: ", self.count_techs_with_customers
  62.         print "     Techs Unavailable: ", self.count_techs_unavailable
  63.         print "     Techs Available: ", self.count_techs_available
  64.  
  65.  
  66. ###### START PRIMARY SCRIPT ######
  67. BH_LOGIN_URL = "https://i.bluehost.com/cgi/admin/provider"
  68. CHATS_URL = "https://i.bluehost.com/cgi-bin/util/live_chat/live_chat?skip_wrapper=1"
  69. CALLS_URL = "https://wallboard.bluehost.com/wallboard/wallboard_call.html"
  70. UNAME = system.exec_command("bash -c 'whoami'", True)
  71.  
  72. ### [0-1] are identical because the class ID for Support Calls and Chats are the same.
  73. ### The order of SELECTED_QUEUES defines final output order
  74. SELECTED_QUEUES = [("Support Calls", "queue_support"), ("Support Chats", "queue_support"), ("Level 3 Calls", "queue_level_3"), ("Dedicated Chats", "queue_dedicated")]
  75. QUEUE_DATA = []
  76.  
  77.  
  78.  
  79. ###### Set up mechanize browser ######
  80. ##Browser
  81. agent = mechanize.Browser()
  82. ##Cookie Jar
  83. cj = cookielib.LWPCookieJar()
  84. ##Browser Options
  85. agent.set_cookiejar(cj)
  86. agent.set_handle_equiv(True)
  87. agent.set_handle_redirect(True)
  88. agent.set_handle_referer(True)
  89. agent.set_handle_robots(False)
  90. agent.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)
  91. ## Adding request headers
  92. agent.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0'),
  93.                                     ('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'),
  94.                                     ('Accept-Language', 'en-gb,en;q=0.5'),
  95.                                     ('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7')]
  96.  
  97.  
  98. ## If cookie not found, log in and store session for use
  99. def bh_login_check():
  100.     agent.open(BH_LOGIN_URL)
  101.     try:
  102.         cj._cookies['i.bluehost.com']['/']['admin_user']
  103.     except KeyError:
  104. #      print "there was an error"
  105.         agent.select_form(name="admin_login_form")
  106.         for control in agent.form.controls:
  107.             if control.name == 'admin_user':
  108.                 agent[control.name] = UNAME
  109.             if control.name == 'admin_pass':
  110.                 retCode, webpass = dialog.password_dialog(title="Login - i.bluehost.com", message="Enter web password for user: \n  %s" % UNAME)
  111.                 agent[control.name] = webpass
  112.        ## submitting the loginform
  113.         response = agent.submit()
  114.         try:
  115.             agent.select_form(name="admin_login_form")
  116.         except mechanize._mechanize.FormNotFoundError:
  117.             return True
  118.         else:
  119.             # TODO: need to get the info dialog to display when auth fails
  120.             #print "Sorry, Cannot Log in to Bluehost. Wrong password?"
  121.             #dialog.info_dialog(title="Authorization Failed", message="Sorry, Cannot Log in to Bluehost. Wrong password?")
  122.             return False
  123. #        print response.read()
  124.  
  125.  
  126. # Check each wallboard queue, collect and store relevant values for the report
  127. def scrape_queues():
  128.     ## Get calls wallboard report
  129.     queue_urls = [CALLS_URL, CHATS_URL]
  130.     for queue_url in queue_urls:
  131.         resource_calls = agent.open(queue_url)
  132.         soup_calls = BeautifulSoup(resource_calls.read())
  133.         support_queues= soup_calls.find_all('div', {'class' : 'queue'})
  134.  
  135.         ## Create queue objects with current values for the appropriate call queues.
  136.         for queue in support_queues:
  137.             queue_type = ""
  138.             queue_name = ""
  139.             queue_awt = 0
  140.             queue_customers_waiting = 0
  141.             queue_calls_waiting = 0
  142.             queue_top_wait_time = 0
  143.             queue_techs_available = 0
  144.             queue_techs_logged_in = 0
  145.             queue_techs_with_customers = 0
  146.             count_techs_unavailable = 0
  147.             queue_techs_available = 0
  148.  
  149.             call_queue = ""
  150.  
  151.             queue_id = queue.get('id')
  152.             if queue_id in dict(SELECTED_QUEUES).values():
  153.                 queue_name = queue.find('td', {'class' : 'top_header'}).contents[0]
  154.                 queue_customers_waiting = queue.find('td', {'class' : 'total_count'}).contents[0]
  155.                 queue_customers_waiting = "".join(line.strip() for line in queue_customers_waiting.split("\n"))
  156.                 queue_top_wait_time = queue.find('td', {'class' : 'top_waiting'}).contents[0]
  157.  
  158.                 if queue_url == CALLS_URL:
  159.                 ## custom Calls-specific attribute
  160.                     queue_type = "call"
  161.                     queue_awt = queue.find('td', {'id' : 'awtTd'}).contents[0]
  162.                     queue_awt = queue_awt.strip(" ")
  163.                     queue_techs_info = queue.find('td', {'id' : lambda L: L and L.startswith('avail_techs')}).contents[0]
  164.                     queue_techs_info = queue_techs_info.strip(" \n")
  165.                     queue_techs_info = re.split('/', queue_techs_info)
  166.                     queue_techs_with_customers = queue_techs_info[0].strip(" \n")
  167.                     queue_techs_logged_in = queue_techs_info[1].strip(" \n")
  168.                     queue_techs_unavailable = queue.findAll('td', {'class' : 'idle_status'})
  169.                     queue_techs_unavailable = len(queue_techs_unavailable)
  170.  
  171.                 elif queue_url == CHATS_URL:
  172.                 # custom Chats-specific attributes
  173.                 ## remeber that while a chatter might be not be available, they may still be on active chat(s)
  174.                 ## only chatters that are both unnavailable and IDLE are not actively taking chats or with active customers
  175.                     queue_type = "chat"
  176.  
  177.                     # find all chatters with a 'red' color class, indicating they are inactive
  178.                     queue_techs_logged_in = int(queue.find(text="Logged In To Chats").findNext('td').contents[0])
  179.                     count_techs_unavailable = int(len(queue.findAll('td', {'style' : 'white-space: nowrap;color:red'})))
  180. #                    count_techs_unavailable = len(queue_techs_unavailable)
  181.  
  182.                     # collect IDLE status chatters and deduct from chatters with customers, since IDLE chatters have no customers
  183.                     queue_techs_idle = queue.findAll('td', {'class' : '_status'})
  184.  
  185.                     ## count the number of IDLE chatters
  186.                     count_techs_idle = 0
  187.                     for i in queue_techs_idle:
  188.                         if i.contents[0] == "IDLE":
  189.                             count_techs_idle += 1
  190.                     # deduct IDLE chatters from from chatters with customers
  191.                     queue_techs_with_customers = queue_techs_logged_in - count_techs_idle
  192.  
  193.                     # count the number of chatters both unnavailable and IDLE
  194.                     count_techs_available = 0
  195. #                    queue_techs_available = queue_techs_logged_in - queue_techs_idle
  196.                     queue_techs_available = queue_techs_logged_in - count_techs_unavailable
  197.  
  198.  
  199.         #    (self, queue_type, queue_id, queue_name, count_customers_in_queue, top_wait_time, avg_wait_time, count_techs_logged_in, count_techs_with_customers, count_techs_unavailable):
  200.                 call_queue = Queue(queue_type, queue_id, queue_name, queue_customers_waiting, queue_top_wait_time, queue_awt, queue_techs_logged_in, queue_techs_with_customers, count_techs_unavailable, queue_techs_available)
  201.                 #call_queue.displayAll()
  202.                 QUEUE_DATA.append(call_queue)
  203.  
  204.  
  205. # Generate usable report output
  206. def report_queues():
  207.     #print SELECTED_QUEUES
  208.     queue_count = len(SELECTED_QUEUES)
  209.     #print "Total queues: ", queue_count
  210.     count = 0
  211.     ## while loop because we are using the order of tuples in SELECTED_QUEUES
  212.     while (count < queue_count):
  213.         queue_name = SELECTED_QUEUES[count]
  214. #        print queue_name[0]
  215.         for q in QUEUE_DATA:
  216.             if q.name == queue_name[0]:
  217.                 output_autokey_values(q)
  218.         count += 1
  219.  
  220.  
  221.  
  222. def output_autokey_values(q):
  223.     # print q.name
  224.     #keyboard.send_keys(q.name + "<tab>")
  225.     #print q.count_customers_in_queue
  226.     keyboard.send_keys(q.count_customers_in_queue + "<tab>")
  227.     if q.type == "call":
  228.         #print q.avg_wait_time
  229.         keyboard.send_keys(q.avg_wait_time + "<tab>")
  230.         if q.name != "Level 3 Calls":
  231.             #print q.count_techs_with_customers
  232.             keyboard.send_keys(str(q.count_techs_with_customers) + "<tab>")
  233.     if q.type == "chat":
  234.         #print q.top_wait_time
  235.         keyboard.send_keys(q.top_wait_time + "<tab>")
  236.     #print q.count_techs_logged_in
  237.     keyboard.send_keys(str(q.count_techs_logged_in) + "<tab>")
  238.     if q.type == "chat":
  239.         #print q.count_techs_available
  240.         keyboard.send_keys(str(q.count_techs_available) + "<tab>")
  241.     #keyboard.send_keys("<enter>")
  242.  
  243.  
  244.  
  245.  
  246.  
  247. ## (TODO?: Google Doc cell population function?)
  248.  
  249.  
  250.  
  251. ##### running
  252. if bh_login_check():
  253.     #print "logged in. yay!"
  254.     #print "scraping wallboards..."
  255.     scrape_queues()
  256.     if QUEUE_DATA:
  257.         report_queues()
  258.     else:
  259.         print "Sorry, no queues collected to report."
Advertisement
Add Comment
Please, Sign In to add comment