SHARE
TWEET

Lvbot2.1

a guest Feb 23rd, 2016 15 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import urllib, urllib2, sys, pycurl, time, random
  2. from BeautifulSoup import BeautifulSoup
  3.  
  4. #Post a notice. Source for 'posted from', replyTo represents message ID you're replying to.
  5. #Leave replyTo blank if not a reply.
  6. def postNotice(message, source, replyTo):
  7.     global username, password
  8.     try:
  9.         c = pycurl.Curl()
  10.         dataArray = {'status':message, 'source':source, 'in_reply_to_status_id':replyTo}
  11.         data = urllib.urlencode(dataArray)
  12.         c.setopt(pycurl.HTTPHEADER, ['User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.'])
  13.         c.setopt(pycurl.POST, True)
  14.         c.setopt(pycurl.WRITEFUNCTION, lambda x: None)
  15.         c.setopt(pycurl.USERPWD, str(username)+':'+str(password))
  16.         c.setopt(pycurl.URL, 'http://rainbowdash.net/api/statuses/update.xml')
  17.         c.setopt(pycurl.POSTFIELDS, data)
  18.         text = c.perform()
  19.         c.close()
  20.         return None
  21.     except Exception as e:
  22.         print e
  23.         sys.exit()
  24.        
  25. #Check how many posts a user has made.
  26. def getNoticeCount(userLink):
  27.     try:
  28.         request = urllib2.Request(userLink, headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.'})
  29.         response = urllib2.urlopen(request)
  30.         data = response.read()
  31.         soup = BeautifulSoup(data)
  32.         count = int(soup.findAll('dl', attrs={'class':'entity_notices'})[0].find('dd').text)
  33.         return count
  34.     except Exception as e:
  35.         print 'You screwed something up.'
  36.         print e
  37.         sys.exit()
  38.        
  39. #Gets HTML for the timeline RSS feed.
  40. def getTimeline():
  41.     try:
  42.         request = urllib2.Request('http://rainbowdash.net/api/statuses/public_timeline.rss', headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.'})
  43.         response = urllib2.urlopen(request)
  44.         data = response.read()
  45.         return data
  46.     except Exception:
  47.         time.sleep(10)
  48.     try:
  49.     request = urllib2.Request('http://rainbowdash.net/api/statuses/public_timeline.rss', headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.'})
  50.         response = urllib2.urlopen(request)
  51.         data = response.read()
  52.         return data
  53.     except Exception as e:
  54.         print 'Could not get timeline. Check site status or tell the programmer he\'s horrible.'
  55.         print 'Send him this, if you do:'
  56.         print e
  57.         sys.exit()
  58.  
  59. #Gets a list of messages, (noticeID, username) format, and returns it.
  60. def getStatuses():
  61.     statusList = []
  62.     soup = BeautifulSoup(getTimeline())
  63.     try:
  64.         for i in soup.findAll('item'):
  65.             username = str(i.find('title').text.split(':')[0])
  66.         message = str(i.find('title').text.split(':')[1])
  67.             noticeID = int(str(i.find('guid').text).split('/')[-1])
  68.             statusList.append((noticeID, username, message))
  69.     except Exception as e:
  70.         print 'Could not parse statuses. Tell the programmer he\'s horrible.'
  71.         print 'Send him this, too:'
  72.         print e
  73.         sys.exit()
  74.     return statusList
  75.  
  76. #Processes a congratulatory message by checking their page,
  77. #and getting the correct message to respond to.
  78. #Otherwise it may respond to the wrong message if someone posts multiple times in a few seconds.
  79. #Also handles if their messages were deleted, reducing their count since last checked.
  80. def processCongratulate(user, number):
  81.     url = 'http://rainbowdash.net/'+str(user)+'/rss'
  82.     request = urllib2.Request(url, headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.'})
  83.     response = urllib2.urlopen(request)
  84.     data = response.read()
  85.     soup = BeautifulSoup(data)
  86.     currentCount = getNoticeCount('http://rainbowdash.net/'+str(user))
  87.     targetNotice = (currentCount - number)
  88.     if(targetNotice >= 0):
  89.         replyTo = int(str(soup.findAll('item')[targetNotice].attrs[0][1]).split('/')[-1])
  90.         return replyTo
  91.     else:
  92.         return None
  93.  
  94. #Congratulates people for every 100,000th message it sees on the timeline.
  95. def specialCongratulate(user, number):
  96.     global specialMessages
  97.     postNotice(random.choice(specialMessages) % (user, number), 'Bot Lounge', number)
  98.     return None
  99.  
  100. #Congratulates people for every 1,000th message they've posted.
  101. def normalCongratulate(user, number, replyTo):
  102.     global normalMessages, redMessages
  103.     replyTo = processCongratulate(user, number)
  104.     if not replyTo:
  105.         return None
  106.     if(str(user) == 'redenchilada'):
  107.         postNotice(random.choice(redMessages) % (user, number), 'Excited Bot Lounge', replyTo)
  108.     else:
  109.         postNotice(random.choice(normalMessages) % (user, number), 'Bot Lounge', replyTo)
  110.     return None
  111.  
  112. #Adds a user to userDict with their post count.
  113. def newUserDict(user, replyTo):
  114.     global userDict, welcomeNew
  115.     userLink = 'http://rainbowdash.net/' + str(user)
  116.     userDict[str(user)] = getNoticeCount(userLink)
  117.     print 'Added ' + str(user) + ' to userDict. Post count: ' + str(userDict[str(user)])
  118.     if(userDict[str(user)] % 1000 == 0):
  119.         normalCongratulate(user, userDict[str(user)], replyTo)
  120.     elif(userDict[str(user)] == 1 and welcomeNew == 'y'):
  121.         welcomeNewUser(str(user), replyTo)
  122.     return None
  123.  
  124. #Increments a user's post count in userDict rather than checking their profile each time.
  125. def updateUserDict(user, replyTo):
  126.     global userDict
  127.     userDict[str(user)] += 1
  128.     if(userDict[str(user)] % 1000 == 0 and userDict[str(user)] != 0):
  129.         normalCongratulate(user, userDict[str(user)], replyTo)
  130.     print str(user) + ' posted. New count: ' + str(userDict[str(user)])
  131.     return None
  132.  
  133. #Gets newest post from the timeline and returns its ID.
  134. def newestNoticeID():
  135.     newNoticeID = 0
  136.     statusList = getStatuses()
  137.     for i in statusList:
  138.         if(i[0] > newNoticeID):
  139.             newNoticeID = i[0]
  140.     return newNoticeID
  141.  
  142. #Runs checks on each status it hasn't seen before.
  143. #Knows if it's seen a message before based on the message's ID.
  144. #Higher ID, newer post.
  145. def findNewStatus():
  146.     global currentNoticeID, userDict
  147.     newMessage = False
  148.     newNoticeID = currentNoticeID
  149.     statusList = getStatuses()
  150.     for i in statusList:
  151.         if(i[0] > currentNoticeID):
  152.         if('@lvbot welcoming on' in i[2]):
  153.         welcomeponyOn(i[1], i[0])
  154.         elif('@lvbot welcoming off' in i[2]):
  155.             welcomeponyOff(i[1], i[0])
  156.             if(i[1] in userDict):
  157.                 updateUserDict(i[1], i[0])
  158.             elif(i[1] not in userDict):
  159.         print 'Adding ' + str(i[1]) + ' to userDict.'
  160.                 newUserDict(i[1], i[0])
  161.             newMessage = True
  162.             if(i[0] > newNoticeID):
  163.                 newNoticeID = i[0]
  164.         if(i[0] % 100000 == 0 and i[0] > currentNoticeID):
  165.             specialCongratulate(i[1], i[0])
  166.     currentNoticeID = newNoticeID
  167.     return newMessage
  168.  
  169. #Turns welcomepony on/off
  170. def welcomeponyOn(username, replyTo):
  171.     global welcomeNew
  172.     postNotice('@'+str(username)+' understood! Turning welcomepony function on.', 'Welcomepony function on', replyTo)
  173.     welcomeNew = 'y'
  174.  
  175. def welcomeponyOff(username, replyTo):
  176.     global welcomeNew
  177.     postNotice('@'+str(username)+' understood! Turning welcomepony function off.', 'Welcomepony function off', replyTo)
  178.     welcomeNew = 'n'
  179.  
  180. #Welcomes new users to be better than WelcomePony
  181. def welcomeNewUser(user, replyTo):
  182.     global welcomeMessages
  183.     postNotice(random.choice(welcomeMessages) % user, 'Bot Lounge', replyTo)
  184.  
  185. #currentNoticeID represents the most recent notice it read,
  186. #userDict stores how many posts each user has.
  187. #Special and normal messages for when people reach a 100,000th RDN message,
  188. #or 1,000th personal message respectively.
  189. welcomeMessages = ['@%s Welcome to RDN! I\'m a bot, but don\'t tell anybody.']
  190. specialMessages = ['@%s Wow. That was RDN\'s %sth dash. That\'s a bunch.',
  191.                    '@%s You made RDN\'s %sth dash. Wow...']
  192. normalMessages = ['@%s Wow, you reached your %sth message. Wow, wow, wow.',
  193.                   '@%s Whoah. %s posts? That\'s about how many times you\'ve posted here. Amazing coincidence.',
  194.                   '@%s Nice job. You reached your %sth post. I wish I had that many.',
  195.                   '@%s Astounding. %s posts. That\'s maybe a hundredth of how many times whats-his-name cried when he played the game [i]To The Moon[/i].']
  196. redMessages = ['@%s Red, you just reached your %sth post.',
  197.                '@%s You know what, Red? You just hit %s posts. How does it feel?',
  198.                '@%s Red, hey, listen, hey, listen, Red, listen, you just hit %s posts.']
  199. currentNoticeID = newestNoticeID()
  200. userDict = {'username':'int'}
  201. username = str(raw_input('Bot username: '))
  202. password = str(raw_input('Bot password: '))
  203. welcomeNew = str(raw_input('Turn on welcoming function? y/n\n'))
  204. wait = 6
  205. findNewStatus()
  206. while(1):
  207.     try:
  208.         print "Checking..."
  209.         newMessage = findNewStatus()
  210.         if(wait <= 38 and not newMessage):
  211.             wait += 2
  212.         elif(newMessage):
  213.             wait = 6
  214.         time.sleep(wait)
  215.     except Exception as e:
  216.         print 'The programmer must suck.'
  217.         print e
  218.         sys.exit()
RAW Paste Data
Top