Advertisement
Guest User

Untitled

a guest
Sep 16th, 2017
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 46.55 KB | None | 0 0
  1. '''This program scrapes craigslist. Still much to be done
  2. to make more robust but this is a stable build on its own
  3.  
  4. Author: https://www.fiverr.com/n3tr1x
  5. '''
  6. print('Loading..')
  7. from time import time
  8. from time import strftime
  9. from time import gmtime
  10. import os
  11. import sys
  12. import traceback
  13. from threading import Timer
  14. import datetime
  15. import re
  16.  
  17. ##To check module loading time
  18. START_TIME = time()
  19. from sys import path as PATH, stdout as STDOUT
  20. PATH.insert(0, './lib/python3.5/site-packages')
  21.  
  22. ##Colorama module to print colored text on the screen
  23. from colorama import init
  24. init()
  25. from colorama import Fore, Back, Style
  26.  
  27. ##Set browser type
  28. ##Change this to CHROME to use chrome. I recommend chrome
  29. TYPE = 'CHROME'
  30. POSTING_REGEX = 'PostingID[^\d]{0,}([\d]{1,})'
  31.  
  32. def pprint(string, color=Fore.GREEN, style=Style.RESET_ALL):
  33. '''
  34. Returns an escaped shell string for pretty printing
  35.  
  36. :Args:
  37. - string - The string to be pretty printed
  38. - color - The ASCII color code to use
  39. - style - Optional style
  40. '''
  41. if not STDOUT.isatty():
  42. return string
  43. try:
  44. c = color + string + style
  45. return c
  46. except:
  47. return string
  48.  
  49. '''
  50. [TODO] Implement this function to dynamically load modules if scale
  51. '''
  52. def load_module(frm, imp, a = ''):
  53. '''
  54. Does the job of importing a module from the system library or local library
  55.  
  56. Arguments:
  57. frm - The name to be used afater python from keyword
  58. imp - The name to be used after python import keyword
  59. a (optional) - The as clause to be used
  60.  
  61. e.g.
  62. load_module('pandas', 'read_sql', 'READ_SQL')
  63. same as: from pandas import read_sql as READ_SQL
  64. '''
  65. try:
  66. s = 'from ' + frm + ' import ' + imp + (' as ' + a if a else '')
  67. exec(s)
  68. return True
  69. except Exception as e:
  70. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint(frm, Fore.YELLOW), str(e))
  71. return False
  72.  
  73. '''
  74. [TODO] Implement this function to dynamically load modules if scale
  75. '''
  76. def load_modules(deps = []):
  77. for dep in deps:
  78. if len(dep) == 2:
  79. if not load_module(dep[0], dep[1]):
  80. exit()
  81. else:
  82. print( pprint('[{0}] checked.. ').format(dep[1]), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  83. elif len(dep) == 3:
  84. if not load_module(dep[0], dep[1], dep[2]):
  85. exit()
  86. else:
  87. print( pprint('[{0}] checked.. ').format(dep[1]), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  88.  
  89.  
  90. print( pprint("\t\t\t\t\t\t==== SCGL BOT v1.0 ====", Fore.BLUE) )
  91. print( pprint("== CHECKING MODULES ==", Fore.YELLOW) )
  92.  
  93. ##Import random
  94. try:
  95. from random import randint as RAND_INT
  96. print( pprint('[{0}] checked.. ').format('random'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  97. except Exception as e:
  98. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('random.randint', Fore.YELLOW), str(e))
  99. exit()
  100. ##import mysql [Important]
  101. try:
  102. from mysql.connector import connect as CONNECT
  103. print( pprint('[{0}] checked.. ').format('mysql'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  104. except Exception as e:
  105. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('mysql', Fore.YELLOW), str(e))
  106. exit()
  107. ##import pandas [Important]
  108. try:
  109. from pandas import read_sql as RSQL
  110. print( pprint('[{0}] checked.. ').format('pandas'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  111. except Exception as e:
  112. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('pandas', Fore.YELLOW), str(e))
  113. exit()
  114. ##import time
  115. try:
  116. from time import sleep
  117. print( pprint('[{0}] checked.. ').format('time.sleep'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  118. except Exception as e:
  119. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('time.sleep', Fore.YELLOW), str(e))
  120. exit()
  121. ##import webdriver [important]
  122. if TYPE.upper() == 'FIREFOX':
  123. try:
  124. from selenium.webdriver import Firefox
  125. print( pprint('[{0}] checked.. ').format('selenium.webdriver.Firefox'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  126. except Exception as e:
  127. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('selenium.webdriver', Fore.YELLOW), str(e))
  128. exit()
  129. ##import firefox-binary
  130. try:
  131. from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
  132. print( pprint('[{0}] checked.. ').format('selenium.webdriver.firefox.firefox_binary'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  133. except Exception as e:
  134. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('selenium.webdriver.firefox.firefox_binary', Fore.YELLOW), str(e))
  135. exit()
  136.  
  137. ##import webdriver [important]
  138. if TYPE.upper() == 'CHROME':
  139. try:
  140. from selenium.webdriver import Chrome
  141. print( pprint('[{0}] checked.. ').format('selenium.webdriver.Chrome'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  142. except Exception as e:
  143. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('selenium.webdriver', Fore.YELLOW), str(e))
  144. exit()
  145.  
  146. ##import By
  147. try:
  148. from selenium.webdriver.common.by import By
  149. print( pprint('[{0}] checked.. ').format('selenium.webdriver.common.by'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  150. except Exception as e:
  151. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('selenium.webdriver.firefox.common.by', Fore.YELLOW), str(e))
  152. exit()
  153. ##import WebDriverWait
  154. try:
  155. from selenium.webdriver.support.ui import WebDriverWait
  156. print( pprint('[{0}] checked.. ').format('selenium.webdriver.support.ui'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  157. except Exception as e:
  158. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('selenium.webdriver.support.ui', Fore.YELLOW), str(e))
  159. exit()
  160. ##import Expected-conditions
  161. try:
  162. from selenium.webdriver.support import expected_conditions as EC
  163. print( pprint('[{0}] checked.. ').format('selenium.webdriver.support'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  164. except Exception as e:
  165. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('selenium.webdriver.support', Fore.YELLOW), str(e))
  166. exit()
  167. ##import Select
  168. try:
  169. from selenium.webdriver.support.select import Select
  170. print( pprint('[{0}] checked.. ').format('selenium.webdriver.support.select'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  171. except Exception as e:
  172. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('selenium.webdriver.support.select', Fore.YELLOW), str(e))
  173. exit()
  174. from selenium.common.exceptions import *
  175. ##import re.sub
  176. try:
  177. from re import sub as REPLACE
  178. print( pprint('[{0}] checked.. ').format('re.sub'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  179. except Exception as e:
  180. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('re.sub', Fore.YELLOW), str(e))
  181. exit()
  182.  
  183. driver = None
  184.  
  185. if TYPE.upper() == 'FIREFOX':
  186. ##check firefox-binary
  187. binary = None
  188. binary_location = r'/usr/bin/firefox-esr'
  189. try:
  190. binary = FirefoxBinary(binary_location)
  191. print( pprint('[{0}] checked.. ').format('Firefox-binary'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  192. except Exception as e:
  193. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint('Firefox-binary', Fore.YELLOW), str(e))
  194. exit()
  195.  
  196. #Check firefox driver
  197. try:
  198. driver = Firefox(firefox_binary=binary)
  199. print( pprint('[{0}] checked.. ').format('Firefox-driver'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  200. except Exception as e:
  201. print(pprint('Error', Fore.RED), pprint('while loading module: '), pprint("Firefox-driver. \nPlease download geckodriver and place in PATH", Fore.YELLOW), str(e))
  202. exit()
  203.  
  204. if TYPE.upper() == 'CHROME':
  205. path_to_cdriver = 'chromedriver'
  206. print( pprint('Loading [{0}].. ').format('Chrome browser'), pprint('Loaded: {0}s', color=Fore.YELLOW).format(time() - START_TIME) )
  207. driver = Chrome(path_to_cdriver)
  208.  
  209.  
  210. print('')
  211. print('')
  212. ##WebWait object
  213. wait = WebDriverWait(driver, 20)
  214.  
  215.  
  216. def wait_load():
  217. """Throws in random waits to not appear as a bot to
  218. craigslist anti-scraping software"""
  219. return sleep(RAND_INT(1, 3))
  220.  
  221.  
  222. BLOCKED_STUB = "This IP has been automatically blocked."
  223.  
  224.  
  225. def load_url(url, callabl, name = 'element', counts=5, **args):
  226. '''
  227. Loads a URL and or check for the callable using webwait
  228. : Args:
  229. - url - The url to load or '' to just wait until element is found
  230. - callabl - The callable object that WebWait calls
  231. - name - The name to be printed as message
  232. - count - The amount of retries after an element is not found
  233. '''
  234. try:
  235. if url != '':
  236. driver.get(url)
  237. while counts > 0:
  238. try:
  239. wait.until(callabl)
  240. return True
  241. except:
  242. cr_miscellany(**args)
  243. counts -= 1
  244. print(pprint("\n[DEBUG] ", Fore.YELLOW), pprint(name, Fore.GREEN))
  245. print('ERROR URL: %s'%(url))
  246. print(pprint('Trying again.. ' + str(counts) + ' more tries left', Fore.YELLOW))
  247. return False
  248. except (RemoteDriverServerException, TimeoutException) as e:
  249. print(pprint('[Error]', Fore.RED), pprint(str(e), Fore.YELLOW))
  250. exit()
  251.  
  252. def url_changed(url):
  253. '''
  254. Checks if URL of the selenium driver has changed
  255. '''
  256. return (url not in driver.current_url)
  257.  
  258. '''
  259. [TODO] Saved state
  260.  
  261. def get_jobs():
  262. fname = os.path.join("jobs", "uncompleted_tasks")
  263. if( not os.path.exists(fname)):
  264. print(pprint('Path: ' + fname + ' does not exist. Creating..', Fore.YELLOW))
  265. os.makedirs("jobs")
  266. with open(fname, mode="w", encoding='utf-8') as f:
  267. f.write('')
  268. if( not os.access(fname, os.R_OK)):
  269. print(pprint('Permission denied: ' + fname, Fore.RED))
  270. return False
  271. with open(fname, encoding='utf-8') as a_file:
  272. return a_file.read()
  273.  
  274. def put_job(name):
  275. fname = os.path.join("jobs", "uncompleted_tasks")
  276. with open(fname, mode='a+', encoding='utf-8') as f:
  277. f.write(name + "\n")
  278.  
  279. def discard_jobs():
  280. fname = os.path.join("jobs", "uncompleted_tasks")
  281. with open(fname, mode="w", encoding='utf-8') as f:
  282. f.write('')
  283.  
  284. def handle_unfinished(info, scrnsht):
  285. jobs_set = set()
  286. try:
  287. for job in get_jobs().split():
  288. jobs_set.add(job)
  289. if len(jobs_set) > 0:
  290. print(pprint( '[DEBUG] ' + str(len(jobs_set)) + ' uncompleted ads detected.. Proceeding to complete them.'))
  291. for j in jobs_set:
  292. j = j.strip()
  293. print(pprint('[INFO] Handling unfinished job: ' + j, Fore.YELLOW))
  294. j_s = j.split('[===]')
  295. if len(j_s) < 4:
  296. return
  297. email_login(unfinished=j_s[0], username=j_s[1], password=j_s[2], ID_MSG = j_s[3] )
  298. complete_post(j_s[0],info, scrnsht)
  299. remove_job(j_s[0])
  300. jobs_set.discard(j)
  301. except Exception as e:
  302. print(pprint('[DEBUG] Cannot handle unfinished jobs'))
  303. print(e)
  304. finally:
  305. write_jobs(jobs_set)
  306.  
  307. def remove_job(url):
  308. jobs_set = set()
  309. try:
  310. for job in get_jobs().split():
  311. jobs_set.add(job)
  312. for j in jobs_set:
  313. j = j.strip()
  314. j_s = j.split('[===]')
  315. if len(j_s) < 4:
  316. return
  317. if url in j_s[0]:
  318. jobs_set.discard(j)
  319. except Exception as e:
  320. print(pprint('[DEBUG] Cannot handle unfinished jobs'))
  321. print(e)
  322. finally:
  323. write_jobs(jobs_set)
  324.  
  325.  
  326. def write_jobs(js):
  327. discard_jobs()
  328. for j in js:
  329. put_job(j)
  330. '''
  331.  
  332. CLIENT = ['']
  333.  
  334. def switch_to_email_tab(user):
  335. print('Searching for the email tab for user: ' + user)
  336. for handle in driver.window_handles:
  337. driver.switch_to.window(handle)
  338. if 'Workspace Webmail' in driver.title:
  339. try:
  340. if user in driver.find_element_by_xpath('//span[@id="username"]').text:
  341. print('Found the tab for user: ' + user)
  342. return True
  343. else:
  344. continue
  345. except:
  346. return False
  347. return False
  348.  
  349. def switch_to_post_tab(link, func=None
  350. ):
  351. print('Searching for the post tab for link: ' + link)
  352. for handle in driver.window_handles:
  353. driver.switch_to.window(handle)
  354. if link in driver.current_url:
  355. try:
  356. func()
  357. except:
  358. pass
  359. break
  360.  
  361. LOGIN_CONTROLLER = dict()
  362. def email_login(username='sales39@containerking.com', password='falcon00', name = 'I', ID_MSG = 'POST/EDIT/DELETE'):
  363. current_url = driver.current_url
  364. if ('craigslist.org' in current_url) and (not 'You should receive an email shortly' in driver.page_source):
  365. print(pprint("No verification mail needed. Returning.. :) "))
  366. return ''
  367. else:
  368. print(pprint("Email verification required.. "))
  369.  
  370. if not (username in LOGIN_CONTROLLER.keys()):
  371. LOGIN_CONTROLLER[username] = False
  372.  
  373. if not LOGIN_CONTROLLER[username]:
  374. print('You are not logged in with: ' + username)
  375. driver.get('https://sso.godaddy.com/login?app=email&realm=pass')
  376. print(pprint("\n==Please wait while " + name + " check your mail=="))
  377. if not load_url('',
  378. EC.presence_of_element_located((By.ID, 'password')),
  379. 'Cannot find password field'):
  380. print('An error occured, Please retry')
  381.  
  382. uname = driver.find_element_by_id('username')
  383. uname.clear()
  384. uname.send_keys(username)
  385. pword = driver.find_element_by_id('password')
  386. pword.clear()
  387. pword.send_keys(password)
  388. driver.find_element_by_xpath('//*[@id="submitBtn"]').click()
  389.  
  390. if not switch_to_email_tab(username):
  391. LOGIN_CONTROLLER[username] = False
  392. return email_login(username, password, name, ID_MSG)
  393.  
  394. if not load_url('',
  395. EC.presence_of_element_located((By.XPATH, '//*[@id="foldertree_INBOX"]//span')),
  396. 'Cannot find Inbox button'):
  397. print('An error occured, Please retry')
  398.  
  399. switch_to_post_tab('post.craigslist', lambda : driver.close())
  400. switch_to_email_tab(username)
  401. LOGIN_CONTROLLER[username] = True
  402. elem = driver.find_element_by_xpath('//*[@id="foldertree_INBOX"]//span')
  403. if not elem.text in 'Inbox':
  404. print(pprint('Godaddy updated their code, Please update email login code', Fore.RED))
  405. elem.click()
  406. if not load_url('',
  407. EC.presence_of_element_located((By.XPATH, '//*[@id="tbody_mailindex"]')),
  408. 'Inbox display'):
  409. print(pprint('An error occured, Please retry', Fore.RED))
  410.  
  411. inbox = None
  412. messages = []
  413. while len(messages) <= 1:
  414. sleep(1)
  415. inbox = driver.find_element_by_id("tbody_mailindex")
  416. messages = inbox.find_elements_by_tag_name('tr')
  417. print(pprint("Looking for unread messages with the keyword: " + ID_MSG, Fore.YELLOW))
  418. print(pprint("\nThere are " + str(len(messages)) + " emails.", Fore.YELLOW))
  419. for message in messages:
  420. tmp_id = message.get_attribute('id')
  421. temp = None
  422. try:
  423. temp = driver.find_element_by_xpath('//tr[@id="' + tmp_id + '"]/td[3]/div/span')
  424. except Exception as e:
  425. print(e)
  426. continue
  427. if not (ID_MSG in temp.text):
  428. continue
  429. if (not 'bold' in message.get_attribute('class')):
  430. continue
  431. temp.click()
  432. if not load_url('',EC.presence_of_element_located((By.XPATH, '//*[@id="wmMessage"]')),'Inbox message check', counts=2):
  433. print(pprint('An error occured, Please retry', Fore.RED))
  434. return email_login(username, password, name, ID_MSG)
  435.  
  436. wm = driver.find_element_by_id('wmMessage')
  437. links = wm.find_elements_by_tag_name('a')
  438. for link in links:
  439. try:
  440. if 'post.craigslist' in link.get_attribute('href'):
  441. href = link.get_attribute('href')
  442. print( pprint('[INFO] Found verification link: ' + href, Fore.YELLOW))
  443. link.click()
  444. wait_load()
  445. return href
  446. except TypeError as e:
  447. pass
  448. except:
  449. pass
  450. return False
  451.  
  452.  
  453. def cr_miscellany(**args):
  454. #dynamically assign variables
  455. for a in args:
  456. exec("%s = '%s'"%(a,args[a]))
  457. try:
  458. del a, args #clear variables assigned
  459. except:
  460. pass
  461.  
  462. current_url = driver.current_url
  463. if current_url.endswith('pn') or current_url.endswith('tou'):
  464. if not load_url('', EC.presence_of_element_located((By.XPATH,
  465. '//*[@class="previewButtons"]')),
  466. 'Accept Terms and Conditions', counts=1):
  467. raise Exception('Phone number verification stuff encountered') #signify phone number verification needed
  468. #Click the accept terms and conditions button
  469. try:
  470. driver.find_element_by_xpath('//section[@class="body"]//section[@class="previewButtons"]//button[@type="submit"]').click()
  471. except:
  472. pass
  473. wait_load()
  474.  
  475. #necessary in case you're logged out
  476. if not load_url('',EC.visibility_of_element_located((By.XPATH, '//*[@name="an"]')),'Continue with credit card', counts=1):
  477. print(pprint('An error occured, Please retry', Fore.RED))
  478. return
  479. try:
  480. driver.find_element_by_xpath('//form[1]//input[@value="ccard"]').click()
  481. wait_load()
  482. except:
  483. pass
  484. try:
  485. driver.find_element_by_xpath('//form[1]//button[@type="submit"]').click()
  486. except:
  487. pass
  488.  
  489.  
  490. #deal with confirmation after billing page
  491. current_url = driver.current_url
  492. if (('craigslist.org' in current_url) and ('You should receive an email shortly'
  493. in driver.page_source)) or current_url.endswith('mailoop'):
  494. print(pprint("Email verification required.. "))
  495. state = email_login(email, password, ID_MSG = title)
  496. if state == False:
  497. raise Exception('Error occured while verifying email')
  498. wait_load()
  499. try:
  500. for handle in driver.window_handles:
  501. driver.switch_to.window(handle)
  502. if state in current_url:
  503. break
  504. except Exception as e:
  505. print(e)
  506.  
  507.  
  508. if BLOCKED_STUB in driver.page_source:
  509. print('Attempting to use pre-coded algorithm to correct IP block')
  510.  
  511. driver.back()
  512. sleep(2)
  513. driver.forward()
  514.  
  515.  
  516. def complete_post(url, infos, scrnsht, email, password, title):
  517. SUCCESSFUL_PURCHASE = False
  518. if len(infos) is 0:
  519. print('Empty credit card info sent')
  520.  
  521. #attempt login incase login wasn't persisted
  522. craigslist_login(email, password)
  523.  
  524. #click continue on billing page
  525. if not load_url('',EC.presence_of_element_located((By.NAME, 'go')),'Continue with credit card button', counts=5, email=email, password=password, ID_MSG=title):
  526. print(pprint('An error occured, Please retry', Fore.RED))
  527. driver.find_element_by_name('go').click()
  528.  
  529.  
  530. if not load_url('',EC.presence_of_element_located((By.XPATH, '//*[@id="ccinfo"]')),'Credit card information'):
  531. print(pprint('An error occured, Please retry', Fore.RED))
  532. driver.find_element_by_name('go').click()
  533. try:
  534. for info in infos:
  535. if info == 'pcard':
  536. continue
  537. if not load_url('',EC.presence_of_element_located((By.NAME, info)),'Providing credit card information: ' + info):
  538. print(pprint('An error occured, Please retry', Fore.RED))
  539.  
  540. if (info in 'cardCountry'):
  541. ccntr = driver.find_elements_by_name(info)
  542. for ctr in ccntr:
  543. if ctr.get_attribute('value') == 'US':
  544. print(pprint('[INFO] Filling: ' + info + ": " + infos[info], Fore.YELLOW))
  545. ctr.click()
  546. print(pprint('[INFO] Filled: ' + info + ": " + infos[info], Fore.YELLOW))
  547. break
  548. continue
  549. if (info in 'cardState'):
  550. cst = driver.find_element_by_name(info)
  551. st = infos[info]
  552. stag = Select(cst)
  553. stag.select_by_visible_text(infos[info])
  554. while True:
  555. try:
  556. print(pprint('[INFO] Filling: ' + info + ": " + infos[info], Fore.YELLOW))
  557. stag.first_selected_option
  558. print(pprint('[INFO] Filled: ' + info + ": " + infos[info], Fore.YELLOW))
  559. break
  560. except:
  561. continue
  562. continue
  563. print('Filling: ' + info + ": " + str(infos[info]))
  564. driver.find_element_by_name(info).send_keys(infos[info])
  565. print('Filled: ' + info + ": " + str(infos[info]))
  566. except Exception as e:
  567. tb = sys.exc_info()[2]
  568. print(tb)
  569. return False
  570. purchase_button = driver.find_element_by_xpath('//div[@id="presubmit"]/button')
  571. try:
  572. purchase_button.click()
  573. wait_load()
  574. if not load_url('',EC.presence_of_element_located((By.XPATH, '//div[@id="presubmit"]/button')),'Using guess to determine if post was successful', counts=1):
  575. SUCCESSFUL_PURCHASE = True
  576. print('Counting the post as success. Checks passed.. If this is wrong, please contact admin')
  577. except Exception as e:
  578. print(e)
  579. return False
  580. #driver.get_screenshot_as_file( str(time()) + '_SUCCESS_' + infos['cardLastName'])
  581. if SUCCESSFUL_PURCHASE:
  582. invoice_elem = driver.find_elements_by_xpath('//table[@id="postingInvoice"]//td')
  583. for inv_elem in invoice_elem:
  584. inv_text = inv_elem.text
  585. m = re.search(POSTING_REGEX, inv_text)
  586. if m:
  587. posting_id = m.group(1)
  588. return posting_id
  589. print(pprint('[DEBUG] Posting ID not found.'), Fore.RED)
  590. else:
  591. return False
  592.  
  593. def breakloop():
  594. eval('break')
  595.  
  596.  
  597. def is_logged_in(username):
  598. return (username == CRAIGSACC_CONTROLLER[0])
  599.  
  600.  
  601. CRAIGSACC_CONTROLLER = ['']
  602. def craigslist_login(username, password):
  603. try:
  604. if (not is_logged_in(username)):
  605. try:
  606. driver.find_element_by_partial_link_text('log in').click()
  607. except:
  608. driver.get('https://accounts.craigslist.org/login/home')
  609. if load_url('',EC.presence_of_element_located((By.ID,
  610. 'paginator')), '', counts=0):
  611. try:
  612. driver.find_element_by_partial_link_text('log out').click()
  613. except:
  614. pass
  615. else:
  616. print(pprint('You are already logged into current city', Fore.BLUE))
  617. return
  618.  
  619.  
  620. driver.find_element_by_id('inputEmailHandle').send_keys(username)
  621. driver.find_element_by_id('inputPassword').send_keys(password)
  622. wait_load()
  623. driver.find_element_by_xpath('//*[@class="accountform-actions"]/button').click()
  624. if not load_url('',EC.presence_of_element_located((By.ID,
  625. 'paginator')), '', counts=5):
  626. print(pprint('Login unsuccessful', Fore.RED))
  627. raise Exception
  628. CRAIGSACC_CONTROLLER[0] = username
  629. except:
  630. print("Encountered an error while I was logging in, Proceeding with error..")
  631. traceback.print_exception(*sys.exc_info())
  632.  
  633. def getinput(prompt, typeCheck=False, obj=None, timeout=30.0):
  634. prompt = prompt + "\n\t\t/QUIT to cancel command prompt\n<> "
  635. retval = False
  636. try:
  637. while True:
  638. inp = input(prompt)
  639. if '/QUIT' not in inp.strip().upper():
  640. return retval
  641. if typeCheck:
  642. try:
  643. retval = obj(inp)
  644. break
  645. except:
  646. continue
  647. else:
  648. retval = inp
  649. break
  650. finally:
  651. return retval
  652.  
  653. def prettify(inp):
  654. if inp is None:
  655. return ''
  656. inp = REPLACE(r'[\r]{1,}[\n]{1,}', '\n', inp)
  657. return inp
  658.  
  659. def craigslist_handler(url, typ, cat, market, title, body, postal, price, email, password, images, pn, sale_man, sale_mod, sale_size):
  660. #images='/root/Documents/slar/crawler/A.jpeg<==>/root/Documents/slar/crawler/B.jpeg<==>/root/Documents/slar/crawler/C.jpeg'
  661. craigslist_login(email, password)
  662. """Main workhorse of the script. This function uses Selenium to automate
  663. posting in the supplied location and category. """
  664. if not load_url(url, EC.presence_of_element_located((By.ID, 'post')),
  665. "I'm unable to find the link to post to classifieds\n", counts=5):
  666. print(pprint('An error occured, Please retry', Fore.RED))
  667.  
  668.  
  669. #if not load_url('https://www.craigslist.org/about/sites',
  670. # EC.presence_of_element_located((By.PARTIAL_LINK_TEXT, market)),
  671. # 'location url'):
  672. # print('An error occured, Please retry')
  673. #
  674. try:
  675. driver.find_element_by_partial_link_text('post to classifieds').click()
  676. except:
  677. try:
  678. driver.find_element_by_xpath('//*[@class="page-container"]//div[@id="leftbar"]//ul[@id="postlks"]//li//a[@id="post"]').click()
  679. except:
  680. driver.find_element_by_id('post').click()
  681. wait_load()
  682. if not load_url('', EC.presence_of_element_located((By.CLASS_NAME, 'picker')),
  683. "Unable to select type", counts=5):
  684. print(pprint('An error occured, Please retry', Fore.RED))
  685.  
  686. select_opts = driver.find_elements_by_xpath('//form[@class="picker"]//ul[@class="selection-list"]//label')
  687. print(pprint("[INFO] Selecting a type", Fore.YELLOW))
  688. for opt in select_opts:
  689. if typ.strip().lower() in opt.find_element_by_class_name('right-side').text.lower():
  690. sleep(3)
  691. opt.find_element_by_tag_name('input').click()
  692. break
  693. wait_load()
  694. if driver.current_url.endswith('type'):
  695. sleep(5)
  696. if driver.current_url.endswith('type'):
  697. driver.find_element_by_name('go').click()
  698. print(pprint("[INFO] Selected type: " + typ, Fore.YELLOW))
  699.  
  700. while True:
  701. if(driver.current_url.endswith('cat')):
  702. break
  703. print(pprint("[INFO] Selecting a category", Fore.YELLOW))
  704. select_opts = driver.find_elements_by_xpath('//form[@class="picker"]//ul[@class="selection-list"]//label')
  705. for opt in select_opts:
  706. if cat.strip().lower() in opt.find_element_by_class_name('right-side').text.lower():
  707. wait_load()
  708. opt.find_element_by_tag_name('input').click()
  709. break
  710. wait_load()
  711. if driver.current_url.endswith('cat'):
  712. sleep(5)
  713. if driver.current_url.endswith('cat'):
  714. driver.find_element_by_name('go').click()
  715. print(pprint("[INFO] Selected category: " + cat.strip(), Fore.YELLOW))
  716.  
  717. MARKET = False
  718. msg = "Subarea is required"
  719. count = 2
  720. try:
  721. while True:
  722. if driver.current_url.endswith('edit'):
  723. break
  724. if not load_url('', EC.presence_of_element_located((By.CLASS_NAME, 'picker')),
  725. msg, counts=count):
  726. break
  727. if(driver.current_url.endswith('subarea')) and (not MARKET):
  728. print(pprint('[INFO] Selecting a subarea', Fore.YELLOW))
  729. if not market:
  730. elems = driver.find_elements_by_xpath('//form[@class="picker"]//ul[@class="selection-list"]//label//input')
  731. print(pprint('Subarea is required but isn\'t provided', Fore.YELLOW))
  732. print(pprint('Using pre-coded guess algorithm to pick one subarea', Fore.YELLOW))
  733. elems[0].click()
  734. MARKET = True
  735. continue
  736. select_opts = driver.find_elements_by_xpath('//form[@class="picker"]//ul[@class="selection-list"]//label')
  737. for opt in select_opts:
  738. if market.strip().lower() in opt.text.lower():
  739. opt.find_element_by_tag_name('input').click()
  740. MARKET = True
  741. break
  742. if not MARKET:
  743. elems = driver.find_elements_by_xpath('//form[@class="picker"]//ul[@class="selection-list"]//label//input')
  744. if len(elems) > 0:
  745. elems[0].click()
  746. msg = "Using pre-coded guess algorithm to check for any unexpected input from craigslist"
  747. count = 1
  748. print(pprint("[INFO] Selected subarea: " + market, Fore.YELLOW))
  749. else:
  750. if driver.current_url.endswith('edit'):
  751. break
  752. if driver.current_url.endswith('subarea') and MARKET:
  753. continue
  754. elems = driver.find_elements_by_xpath('//form[@class="picker"]//ul[@class="selection-list"]//label//input')
  755. if len(elems) > 0:
  756. elems[0].click()
  757. else:
  758. break
  759. except:
  760. pass
  761.  
  762. wait_load()
  763. while True:
  764. if(driver.current_url.endswith('edit')):
  765. break
  766. print(pprint('[INFO] Filling post information', Fore.YELLOW))
  767. if not load_url('', EC.presence_of_element_located((By.ID, 'postingForm')),
  768. "Unable to get the posting form", counts=5):
  769. print(pprint('An error occured, Please retry', Fore.RED))
  770.  
  771. driver.find_element_by_name('PostingTitle').send_keys(title)
  772. driver.find_element_by_name('Ask').send_keys(price)
  773. driver.find_element_by_name('postal').send_keys(postal)
  774. driver.find_element_by_name('GeographicArea').send_keys(market)
  775. driver.find_element_by_name('PostingBody').send_keys(prettify(body))
  776. driver.find_element_by_name('sale_manufacturer').send_keys(sale_man)
  777. driver.find_element_by_name('sale_model').send_keys(sale_mod)
  778. driver.find_element_by_name('sale_size').send_keys(sale_size)
  779. driver.find_element_by_name('wantamap').click()
  780. try:
  781. driver.find_element_by_name('FromEMail').send_keys(prettify(email))
  782. driver.find_element_by_name('ConfirmEMail').send_keys(prettify(email))
  783. except:
  784. pass
  785. driver.find_element_by_xpath(
  786. '//*[@id="contact_phone"]').send_keys(pn)
  787. sleep(2)
  788. print(pprint('[INFO] Sending post information', Fore.YELLOW))
  789. driver.find_element_by_name('go').click()
  790. wait_load()
  791. '''
  792. while True:
  793. if(driver.current_url.endswith('geoverify')):
  794. break
  795. wait_load()
  796. print(pprint('[INFO] Confirming post location', Fore.YELLOW))
  797. if not load_url('', EC.presence_of_element_located((By.ID, 'leafletForm')),
  798. "Unable to get the posting form", counts=5):
  799. print(pprint('An error occured, Please retry', Fore.RED))
  800.  
  801. driver.find_element_by_id('leafletForm').find_element_by_xpath('//button[@class="continue bigbutton"]').click()
  802. print(pprint("[INFO] Post location confirmed ", Fore.YELLOW))
  803. wait_load()
  804. '''
  805. try:
  806. if load_url('', EC.presence_of_element_located((By.ID, 'uploader')),
  807. "Unable to get the posting images", counts=2):
  808. try:
  809. driver.find_element_by_id('classic').click()
  810. except:
  811. pass
  812. if not load_url('', EC.presence_of_element_located((By.XPATH, '//form[@class="add"]//input[@name="file"]')),
  813. "Unable to get the posting form", counts=5):
  814. print(pprint('An error occured while processing upload, Please retry', Fore.YELLOW))
  815. if images:
  816. image_arr = images.split('<==>')
  817. for image in image_arr:
  818. image = image.strip()
  819. if not (os.path.exists(image)):
  820. print(pprint('[DEBUG]'), ' Image: ' + image + ' does not exist.. Proceeding')
  821. continue
  822. inps = driver.find_elements_by_tag_name('input')
  823. for inp in inps:
  824. if 'file' in inp.get_attribute('type'):
  825. try:
  826. print(pprint('Uploading image: ' + image, Fore.BLUE))
  827. inp.clear()
  828. inp.send_keys(image)
  829. driver.find_element_by_xpath('//form[@class="add"]').submit()
  830. if not load_url('', EC.presence_of_element_located((By.XPATH, '//div[@class="imgwrap"]//img')), "Uploading image..", counts=6):
  831. print(pprint('An error occured while processing upload, Please retry', Fore.YELLOW))
  832. print(pprint('Image: ' + image + ' uploaded', Fore.BLUE))
  833. except Exception:
  834. print(pprint('Error: ' + str(e) + ' occured while uploading.', Fore.RED))
  835. tb = sys.exc_info()[2]
  836. print(pprint("[DEBUG] More info:\n\t\t " + tb, Fore.YELLOW))
  837. break
  838. driver.find_element_by_xpath('//button[@class="done bigbutton"]').click()
  839. wait_load()
  840. except:
  841. print(pprint('[DEBUG] Image(s) not uploaded. Proceeding that way'))
  842. traceback.print_exception(*sys.exc_info())
  843. print(pprint('Publishing..'))
  844. if not load_url('', EC.presence_of_element_located((By.NAME, 'go')), "Publish button", counts=5):
  845. print(pprint('An error occured while processing upload, Please retry', Fore.YELLOW))
  846. driver.find_element_by_name('go').click()
  847. print(pprint("\nI've published a draft to post the ad: " + title, Fore.YELLOW))
  848. print(pprint("Proceeding to verify the post.. Please be patient", Fore.YELLOW))
  849.  
  850.  
  851. def publish_post(url, typ, cat, market, title, body, postal, price,
  852. email='sales39@containerking.com', password='falcon00', info={}, scrnsht=str(time()) + 'screenshot.png',
  853. images=False, pn='', sale_man='', sale_mod='', sale_size=''):
  854. # [TODO] handle_unfinished(info, scrnsht)
  855. try:
  856. status = False
  857. post_time = time()
  858. craigslist_handler(url, typ, cat, market, title, body,
  859. postal, price, email, password, images, pn, sale_man,
  860. sale_mod, sale_size)
  861. # [TODO] put_job(href + '[===]' + email + '[===]' + password + '[===]' + title)
  862. state = email_login(email, password, ID_MSG = title)
  863. if state == False:
  864. completed_time = time()
  865. return status, (completed_time - post_time)
  866. wait_load()
  867. try:
  868. for handle in driver.window_handles:
  869. driver.switch_to.window(handle)
  870. if state in driver.current_url:
  871. break
  872. except Exception as e:
  873. print(e)
  874. status = complete_post(state, info, scrnsht, email, password, title)
  875. completed_time = time()
  876. return status, (completed_time - post_time)
  877. except:
  878. traceback.print_exception(*sys.exc_info())
  879. return False, None
  880.  
  881. def cleanup_tabs():
  882. for handle in driver.window_handles:
  883. driver.switch_to.window(handle)
  884. if 'post.craigslist' in driver.current_url:
  885. print(pprint('[INFO] Closing: ' + driver.title, Fore.YELLOW))
  886. driver.close()
  887.  
  888. #all post objects go in here
  889. POSTS_CONTROLLER = {}
  890.  
  891. def check_market(post_title,post_id, market_url, city, limit = 5):
  892. if limit == 0:
  893. limit = 5
  894. print(pprint('[INFO] Checking market if ' + str(post_title)+ " (" + str(post_id) + ') post is in ' + city + ' top ' + str(limit)))
  895. if not load_url(market_url, EC.presence_of_element_located((By.ID, 'sortable-results')) ,"Markets result info", counts=5):
  896. print(pprint('An error occured while checking the market: ' + market_url + ', Please retry', Fore.YELLOW))
  897. total_res = len(driver.find_elements_by_xpath('//div[@id="sortable-results"]/ul[@class="rows"]/li[@class="result-row"]/p[@class="result-info"]'))
  898.  
  899. print(pprint('[INFO] I can see ' + str(total_res) + ' ads on ' + city + '\'s page', Fore.YELLOW))
  900.  
  901. XP = '//div[@id="sortable-results"]/ul[@class="rows"]/li[@class="result-row"][position() < ' + str(limit + 1) + ']'
  902. top_posts = driver.find_elements_by_xpath(XP)
  903. print(pprint('[INFO] Looking for the post: ' + str(post_title)+ " (" + str(post_id) + ') in ' + city, Fore.YELLOW))
  904. for i in range(0, len(top_posts)):
  905. if i >= limit:
  906. break
  907. top_post = top_posts[i].get_attribute('data-pid')
  908. if top_post in str(post_id):
  909. print(post_id + ' in top: ' + str(limit))
  910. return True
  911. print (top_post)
  912. return False
  913.  
  914.  
  915. SERVER_CONNECTOR = [None]
  916. def update_posts_db(city, state, cat, time, pid, posting_id):
  917. try:
  918. if not SERVER_CONNECTOR[0]:
  919. print(pprint('[DEBUG] Cannot find the server connector object'))
  920. cur = SERVER_CONNECTOR[0].cursor()
  921. cur.execute( "INSERT INTO CraigslistPoster.posts(`client`, `postingID`, `post_id`, `market_city`, `market_state`, `category`, `POST_TIME`) VALUES(%s, %s, %s, %s, %s, %s, %s)", (CLIENT[0], str(posting_id), str(pid), str(city), str(state), str(cat), time))
  922. print('Post db updated %s'%(str(ret)))
  923. SERVER_CONNECTOR[0].commit()
  924. except:
  925. traceback.print_exception(*sys.exc_info())
  926.  
  927.  
  928. def handle_dump(pdump):
  929. return publish_post(url=pdump['ad_url'], typ=pdump['typ'],
  930. cat=pdump['cat'],market=pdump['market'],title=pdump['title'],
  931. body=pdump['body'],
  932. postal=pdump['postal'], price=pdump['price'], email=pdump['email'],
  933. password=pdump['password'], images=pdump['images'], info = pdump['info'],
  934. pn = pdump['pn'], sale_man=pdump['sale_man'], sale_mod=pdump['sale_mod'],
  935. sale_size=pdump['sale_size'])
  936.  
  937.  
  938. def check_posts_db(pid, city, delay):
  939. try:
  940. if not SERVER_CONNECTOR[0]:
  941. print(pprint('[DEBUG] Cannot find the server connector object'))
  942. cur = SERVER_CONNECTOR[0].cursor(buffered=True)
  943. cur.execute("SELECT * FROM `posts` WHERE `market_city` LIKE '%%%s%%'"%(city))
  944. NON_EMPTY = False
  945. for x in cur:
  946. NON_EMPTY = True
  947. if not NON_EMPTY:
  948. print(pprint('Not yet registered.. Proceeding', Fore.BLUE))
  949. return True
  950. cur.execute("SELECT POST_TIME, postingID FROM CraigslistPoster.posts WHERE `post_id` = %s ORDER BY `POST_TIME` DESC LIMIT 1", (str(pid),))
  951. for then, pid in cur:
  952. now = datetime.datetime.now()
  953. if ((now - then).total_seconds()) > delay:
  954. return pid
  955. else:
  956. print(pprint('%d minutes left..'%((delay/60) - ((now - then).total_seconds()/60) ), Fore.BLUE))
  957. return False
  958. except:
  959. traceback.print_exception(*sys.exc_info())
  960.  
  961. #Unsuccessful ads
  962. US_ADS = []
  963.  
  964. #Skipped ads
  965. SK_ADS = []
  966.  
  967. #Successful ads
  968. SU_ADS = []
  969.  
  970. #Incomplete ads
  971. INC_ADS = []
  972.  
  973.  
  974. AD_IN_PROGRESS = [False]
  975. def handle_market(ads):
  976. status = None
  977. t_o_c = None
  978. murl = ads['m_url']
  979. mlim = ads['m_lim']
  980. delay = ads['del'] * 60
  981. city = ads['m_cit']
  982. state = ads['m_sta']
  983. post_id = ads['pid']
  984. INC_ADS.append("City: %s; PID: %s"%(city,str(post_id)))
  985. try:
  986. postingID = check_posts_db(post_id, city, delay)
  987. if postingID:
  988. if (not check_market(ads['title'], postingID, murl, city, mlim)):
  989. while AD_IN_PROGRESS[0]:
  990. print(pprint('[INFO] An ad in progress.. Queueing'))
  991. sleep(5)
  992. AD_IN_PROGRESS[0] = True
  993. status, t_o_c = handle_dump(ads)
  994. else:
  995. print(pprint('[INFO] %s\'s not ready. Running to the next city :)'%(city)))
  996. INC_ADS.pop()
  997. SK_ADS.append("City: %s; PID: %s"%(city,str(post_id)))
  998. return
  999. else:
  1000. print(pprint('[INFO] %s\'s not ready. Running to the next city :)'%(city)))
  1001. INC_ADS.pop()
  1002. SK_ADS.append("City: %s; PID: %s"%(city,str(post_id)))
  1003. return
  1004. if not status:
  1005. print(pprint('[ERROR] An error occured while posting to: ' + city, Fore.RED))
  1006. AD_IN_PROGRESS[0] = False
  1007. INC_ADS.pop()
  1008. US_ADS.append("City: %s; PID: %s"%(city,str(post_id)))
  1009. return
  1010. else:
  1011. #status here is posting_id [TODO] Clean up later
  1012. update_posts_db(city, state, ads['cat'], datetime.datetime.now(), post_id, status)
  1013. AD_IN_PROGRESS[0] = False
  1014. except:
  1015. traceback.print_exception(*sys.exc_info())
  1016. INC_ADS.pop()
  1017. US_ADS.append("City: %s; PID: %s"%(city,str(post_id)))
  1018. return
  1019. print(pprint('Ad posted to: {0} in: {1}'.format(city,t_o_c)))
  1020. INC_ADS.pop()
  1021. SU_ADS.append("City: %s; PID: %s"%(city,str(post_id)))
  1022.  
  1023.  
  1024. def manage_posts(ads):
  1025. print('%d ads/market recorded for: %s'%(len(ads), CLIENT[0]))
  1026. for i in range(0, len(ads)):
  1027. print(pprint('======================= ad: %d ========================'%(i + 1)), end="\n\n")
  1028. try:
  1029. handle_market(ads[i])
  1030. print("Leaving " + str(ads[i]['m_cit']) + " Delay time: " + str(ads[i]['del']) + "mins")
  1031. except:
  1032. pass
  1033.  
  1034.  
  1035. '''
  1036. [TODO]
  1037. class Post:
  1038. \'''
  1039. A portable object representation of a post
  1040.  
  1041. e.g. with field types for the use of publish post
  1042. \'''
  1043.  
  1044. def __init__(self):
  1045. #Post id should be replaced by a real hash code generator
  1046. post_id = None
  1047. self['url] = ''
  1048. self.typ = ''
  1049. self.cat = ''
  1050. self.market = ''
  1051. self.title = ''
  1052. self.body = ''
  1053. self.postal = ''
  1054. self.price = ''
  1055. self.email = ''
  1056. self.password = ''
  1057. self.images = []
  1058. self.ccinfo = {}
  1059.  
  1060. def setType(self, t):
  1061. self.typ = t
  1062.  
  1063. def setUrl(self, u):
  1064. self.post_url = u
  1065.  
  1066. def setCat(self, c):
  1067. self.cat = c
  1068.  
  1069. def setMarket(self, c):
  1070. self.market = c
  1071.  
  1072. def setTitle(self, c):
  1073. self.title = c
  1074.  
  1075. def setBody(self, c):
  1076. self.body = c
  1077.  
  1078. def setPostal(self, c):
  1079. self.postal = c
  1080.  
  1081. def setPrice(self, c):
  1082. self.price = c
  1083.  
  1084. def setEmail(self, c):
  1085. self.email = c
  1086.  
  1087. def setPassword(self, c):
  1088. self.password = c
  1089.  
  1090. def addImage(self, c):
  1091. self.images.append(c)
  1092.  
  1093. def setImages(self, c):
  1094. self.images = c
  1095.  
  1096. def setCcinfo(self, c):
  1097. self.ccinfo = c
  1098.  
  1099. def appendCcinfo(self, field, value):
  1100. self.ccinfo[field] = value
  1101.  
  1102. '''
  1103.  
  1104. def read_data_from_sql_db(connection, sql):
  1105. df = RSQL(con=connection,sql=sql)
  1106. dataframe_dict = df.to_dict()
  1107. return dataframe_dict
  1108.  
  1109. def prettify(inp):
  1110. if inp is None:
  1111. return ''
  1112. inp = inp.strip()
  1113. inp = inp.replace('\r', '')
  1114. return inp
  1115.  
  1116. def handle_ads_data(dic):
  1117. total_ads = len(dic['search_url'].values())
  1118. if total_ads < 0:
  1119. return False
  1120. ad_dict = {'typ' : ['type'], 'cat' : ['category'], 'market' : ['tags'], 'title' : ['title'],
  1121. 'body' : ['description'], 'password' : ['password'], 'price' : ['price'], 'postal' : ['postalcode'],
  1122. 'email' : ['email'], 'images' : ['images'], 'sale_man': ['tag1'], 'sale_mod': ['tag2'],
  1123. 'sale_size': ['tag3'], 'pid' : ['market', int], 'del': ['delay', float], 'm_url' : ['search_url'],
  1124. 'm_lim' : ['post_above', int], 'm_cit' : ['market_city'], 'm_sta' : ['market_state'],
  1125. 'ad_url' : ['post_url'], 'pn' : ['phone_no']}
  1126. return parse_db_item(dic, total_ads, ad_dict)
  1127.  
  1128. def handle_cc_data(dic, ads):
  1129. total_ads = len(dic['number'].values())
  1130. if total_ads < 0:
  1131. return False
  1132. ad_dict = {'cardNumber' : ['number', int], 'cvNumber' : ['cvv', int], 'expMonth' : ['exp_month', int],
  1133. 'expYear': ['exp_year', int], 'cardFirstName' : ['firstname'], 'cardLastName' : ['lastname'],
  1134. 'cardAddress': ['address'], 'cardCity' : ['city'], 'cardState' : ['state'], 'cardPostal': ['postalcode', int],
  1135. 'contactPhone': ['phone'], 'pcard': ['primarycard', bool]}
  1136. ret = parse_db_item(dic, total_ads, ad_dict)
  1137. for i in range(0, len(ret)):
  1138. if ret[i]['pcard'] == False:
  1139. continue
  1140. ret[i]['cardCountry'] = "US"
  1141. ret[i]['contactName'] = ret[i]['cardFirstName'] + " " + ret[i]['cardLastName']
  1142. cardinfo = ret[i]
  1143. for i in range(0, len(ads)):
  1144. ads[i]["info"] = cardinfo
  1145. break
  1146. return ads
  1147.  
  1148.  
  1149. def parse_db_item(dic, total_ads, parse_dict):
  1150. ret = list()
  1151. for i in range(0, total_ads):
  1152. retval = dict()
  1153. for item in parse_dict:
  1154. parse_val = parse_dict[item]
  1155. item_idx = parse_val[0]
  1156. item_val = None
  1157. try:
  1158. item_val = dic[item_idx][i]
  1159. except:
  1160. pass
  1161. if item_val is None:
  1162. if len(parse_val) > 1:
  1163. if parse_val[1] is int:
  1164. item_val = 0
  1165. if parse_val[1] is float:
  1166. item_val = 0.0
  1167. else:
  1168. item_val = ''
  1169. if isinstance(item_val, str):
  1170. item_val = item_val.strip()
  1171. if len(parse_val) > 1:
  1172. try:
  1173. parse_val[1](item_val)
  1174. item_val = parse_val[1](item_val)
  1175. except:
  1176. pass
  1177. retval[item] = item_val
  1178. ret.append(retval)
  1179. return ret
  1180.  
  1181.  
  1182. #provide info about unsuccessful, successful and incomplete ads
  1183. def account():
  1184. print(pprint('UNSUCCESSFUL ADS: %d.'%(len(US_ADS)), Fore.BLUE))
  1185. for i in range(0, len(US_ADS)):
  1186. print(pprint("\t\t%s"%(US_ADS[i]), Fore.BLUE))
  1187.  
  1188. print(pprint('INCOMPLETE ADS: %d.'%(len(INC_ADS)), Fore.BLUE))
  1189. for i in range(0, len(INC_ADS)):
  1190. print(pprint("\t\t%s"%(INC_ADS[i]), Fore.BLUE))
  1191.  
  1192. print(pprint('SKIPPED ADS: %d.'%(len(SK_ADS)), Fore.BLUE))
  1193. for i in range(0, len(SK_ADS)):
  1194. print(pprint("\t\t%s"%(SK_ADS[i]), Fore.BLUE))
  1195.  
  1196. print(pprint('SUCCESSFUL ADS: %d.'%(len(SU_ADS)), Fore.BLUE))
  1197. for i in range(0, len(SU_ADS)):
  1198. print(pprint("\t\t%s"%(SU_ADS[i]), Fore.BLUE))
  1199.  
  1200.  
  1201. def initAll():
  1202. #Unsuccessful ads
  1203. US_ADS = []
  1204.  
  1205. #Skipped ads
  1206. SK_ADS = []
  1207.  
  1208. #Successful ads
  1209. SU_ADS = []
  1210.  
  1211. #Incomplete ads
  1212. INC_ADS = []
  1213.  
  1214.  
  1215. def main():
  1216. RESTING_TIME = 120 #time to rest in secs after a round of post
  1217. bot_name = 'Gideon'
  1218. print(pprint('Hi, I\'m %s. Nice to meet you.'%(bot_name), Fore.BLUE))
  1219. while True:
  1220. try:
  1221. initAll()
  1222. print('')
  1223. print(pprint('[INFO] Trying to reach the server'))
  1224. conn = CONNECT(user='admin', password='noobzilla1', database='CraigslistPoster', port='3306',
  1225. host='digitechautomation.cywrzfld2wji.us-west-2.rds.amazonaws.com')
  1226. print(pprint('Server reached..'))
  1227. print('')
  1228. SERVER_CONNECTOR[0] = conn
  1229. CLIENT[0] = 'Container King'
  1230. #posts_data = read_data_from_sql_db(conn, sql="SELECT * FROM CraigslistPoster.posts WHERE client = '%s'"%(CLIENT[0]))
  1231. #cities_data = read_data_from_sql_db(conn, sql="SELECT * FROM CraigslistPoster.markets WHERE client = '%s'"%(CLIENT[0]))
  1232. #container_data = read_data_from_sql_db(conn, sql="SELECT * FROM CraigslistPoster.ads WHERE client = '%s'"%(CLIENT[0]))
  1233. container_data = read_data_from_sql_db(conn, sql="SELECT ads.id, ads.market, ads.client, ads.type, ads.category, ads.tags, ads.tag1, ads.tag2, ads.tag3, ads.title, ads.description, ads.price, ads.postalcode, ads.email, ads.password, ads.images, markets.market_city, markets.market_state, markets.phone_no, markets.delay, markets.post_above, markets.post_url, markets.search_url FROM ads INNER JOIN markets ON ads.market = markets.id WHERE ads.client = '%s'"%(CLIENT[0]))
  1234. payments_data = read_data_from_sql_db(conn, sql="SELECT * FROM CraigslistPoster.payments WHERE client = '%s'"%(CLIENT[0]))
  1235. ads = handle_ads_data(container_data)
  1236. ads = handle_cc_data(payments_data, ads)
  1237. #print(cities_data)
  1238. #print('========================')
  1239. #print(container_data)
  1240. #print(ads)
  1241. manage_posts(ads)
  1242. #rest after posting all ads
  1243. print(pprint('Sleeping.. I\'ll be awake in %d mins'%(RESTING_TIME/60), Fore.BLUE))
  1244. account()
  1245. sleep(RESTING_TIME)
  1246. print('')
  1247. print(pprint('I\'m awake now', Fore.BLUE))
  1248. except:
  1249. account()
  1250.  
  1251. if __name__ == "__main__":
  1252. main()
  1253. exit()
  1254.  
  1255. #email_login()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement