AverageMan

Average Man's PiTFT PyGame Social Network Monitor

Jun 24th, 2015
480
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #
  2. #############################################################################################################
  3. ## PiTFT Social Media Monitor by @AverageManVsPi http://AverageManVsRaspberryPi.com                        ##
  4. ##                                                                                                         ##
  5. ## --> Original basic PyGame example: http://home.uktechreviews.com                                        ##
  6. ## --? Urllib2 tutorial: (Kickstarter tracker: http://raspi.tv/                                            ##
  7. ##                                                                                                         ##
  8. ## This project uses PyGame on the Adafruit PiTFT (original model) to make a social media monitor          ##
  9. ## The monitor checks my Twitter, Facebook, Google+ and Pinterest follower counts every 45 seconds           ##
  10. ##                                                                                                         ##
  11. ## To find out more on the various blocks of code that make this happen, go to AverageManVsRaspberryPi.com ##
  12. ##                                                                                                         ##
  13. ## DISCLAIMER: I no expert. Not even close.                                                                ##
  14. ## This code is probably poor for many reasons including my commenting style -  but it works!              ##
  15. ##                                                                                                         ##
  16. #############################################################################################################
  17.  
  18. ###########
  19. # IMPORTS #
  20. ###########
  21.  
  22. import sys, pygame
  23. from pygame.locals import *
  24. import time
  25. import subprocess
  26. import os
  27. from urllib2 import Request, urlopen, URLError
  28.  
  29. #######################################################################
  30. # SET UP THE PITFT TO WORK WITH PYGAME                                #
  31. #                                                                     #
  32. # This part is necessary to make PyGame work with the PiTFT (I think) #
  33. #                                                                     #
  34. #######################################################################
  35.  
  36. os.environ["SDL_FBDEV"] = "/dev/fb1"
  37. os.environ["SDL_MOUSEDEV"] = "/dev/input/touchscreen"
  38. os.environ["SDL_MOUSEDRV"] = "TSLIB"
  39.  
  40. ###########################################################
  41. # INITIALIZE THE PYGAME FONT MODULE                       #
  42. #                                                         #
  43. # Supposedly nothing will work if you don't do this part! #
  44. #                                                         #
  45. ###########################################################
  46.  
  47. pygame.init()
  48.  
  49. ######################################################
  50. # SET THE GLOBAL FONT                                #
  51. #                                                    #
  52. # This can be overridden for individual items/labels #
  53. #                                                    #
  54. ######################################################
  55.  
  56. font=pygame.font.Font(None,24)
  57.  
  58. ###############################################################################################
  59. # DEFINE WHAT HAPPENS WHEN YOU CLICK CERTAIN AREAS OF THE SCREEN                              #
  60. #                                                                                             #
  61. # This will commonly be used for making simple buttons on screen. I've used this to exit.     #
  62. #                                                                                             #
  63. # As an example, look at the code below:                                                      #
  64. #                                                                                             #
  65. # if 15 <= click_pos[0] <= 125 and 15 <= click_pos[1] <=50:                                   #
  66. #                                                                                             #
  67. # This creates a rectangle clicking shape (not visible) by using X (across) and Y (down) axis #
  68. # It's always starting from the top-left corner                                               #
  69. # Consider the "and" as the splitter between X and Y                                          #
  70. # It's making the X axis line from 15 across to 125 across                                    #
  71. # Then making the Y axis line from 15 down to 50 down                                         #
  72. # This gives you two lines making a right-angle, which is our rectangle                       #
  73. # (PyGame makes a rectangle out of this - we don't need to add the other two lines            #
  74. #                                                                                             #
  75. ###############################################################################################
  76.  
  77. def on_click():
  78.     click_pos = (pygame.mouse.get_pos() [0], pygame.mouse.get_pos() [1])
  79.  
  80.     # Check to see if screen has been pressed
  81.     if 1 <= click_pos[0] <= 320 and 1 <= click_pos[1] <=240: #This uses the entire screen i.e.e click anywhere to exit
  82.         print "You pressed exit" # Print a message to Terminal for our information
  83.         button(0) # Run the 'button' module (0)
  84.  
  85. ######################################
  86. # DEFINE THE BUTTON PRESSING ACTIONS #
  87. ######################################
  88.  
  89. def button(number):
  90.     print "User requested to close GUI" # Prints a message to the screen telling us we selected to exit
  91.     if number == 0: # button(0) - see 'def on_click()' above
  92.  
  93.         # There are 3 Parts to this on-screen message, simply to emulate moving dots on the exit message
  94.  
  95.         # Part 1
  96.         screen.fill(black) #Fill the screen with my pre-defined colour
  97.         font=pygame.font.Font(None,40) # Font size
  98.             label=font.render("Closing system.", 1, (white)) # define exit message and colour
  99.             screen.blit(label,(55,110)) # Blits this new label onto the screen - numbers are distance from left then top (left,top)
  100.         time.sleep(0.3) # Wait less than a second then continue
  101.  
  102.         # Part 2
  103.         screen.fill(black)
  104.         font=pygame.font.Font(None,40)
  105.             label=font.render("Closing system..", 1, (white))
  106.             screen.blit(label,(55,110))
  107.         time.sleep(0.3)
  108.  
  109.         # Part 3
  110.         screen.fill(black)
  111.         font=pygame.font.Font(None,40)
  112.             label=font.render("Closing system...", 1, (white))
  113.             screen.blit(label,(55,110))
  114.        
  115.         # Exit the script (back to terminal)
  116.         sys.exit()
  117.  
  118. #############################################################
  119. # DEFINE RGB COLOURS TO BE USED IN THIS SCRIPT              #
  120. #                                                           #
  121. # I have added some colours for you                         #
  122. # For more, go to http://www.color-hex.com/color-names.html #
  123. #                                                           #
  124. #############################################################
  125.  
  126. white = 255, 255, 255
  127. black = 0, 0, 0
  128. grey = 238, 238, 238
  129. gold = 255, 215, 0
  130. red = 255, 0, 0
  131.  
  132. #######################
  133. # SET THE SCREEN SIZE #
  134. #######################
  135.  
  136. size = width, height = 320, 240 # Set the PiTFT screen size (320x240)
  137.  
  138. ##################################################
  139. # CREATE THE DISPLAY SURFACE AT THE SIZE DEFINED #
  140. ##################################################
  141.  
  142. screen = pygame.display.set_mode(size) # Size is defined separately (above)
  143.  
  144. #########################################################################################################
  145. # INITIAL 'SPLASH' SCREEN TO SHOW THE DISPLAY IS LOADING                                                #
  146. #                                                                                                       #
  147. # There are 3 parts to this, and the only difference is that each part adds another '.' after 'Loading' #
  148. # This gives the impression that something is happening (but nothing is - just a bit of fun             #
  149. # The time.sleep after each part is how long before the next '.' shows                                  #
  150. # After 3 '.' show, the main GUI starts within the While loop                                           #
  151. #                                                                                                       #
  152. #########################################################################################################
  153.  
  154. # Part 1
  155. screen.fill(black) #Fill the screen with my pre-defined colour
  156. fontloading=pygame.font.Font(None,40) # Font size
  157. label=fontloading.render("Loading.", 1, (white)) # Define the message and colour
  158. screen.blit(label,(100,110)) # Blits this new label onto the screen - numbers are distance from left then top (left,top)
  159. pygame.display.flip() # I think this pushes my screen layout defined above - to the screen?
  160. time.sleep(0.3) #Wait
  161.  
  162. # Part 2
  163. screen.fill(black)
  164. fontloading=pygame.font.Font(None,40)
  165. label=fontloading.render("Loading..", 1, (white))
  166. screen.blit(label,(100,110))
  167. pygame.display.flip()
  168. time.sleep(0.3)
  169.  
  170. # Part 3
  171. screen.fill(black)
  172. fontloading=pygame.font.Font(None,40)
  173. label=fontloading.render("Loading...", 1, (white))
  174. screen.blit(label,(100,110))
  175. pygame.display.flip()
  176. time.sleep(0.3)
  177.  
  178. #########################################################################
  179. # Set an initial value for our time checking function in the While loop #
  180. #########################################################################
  181.  
  182. timelastchecked = 0
  183.  
  184. ############################################################################################################################
  185. # WHILE LOOP TO MANAGE TOUCH SCREEN INPUTS                                                                                 #
  186. #                                                                                                                          #
  187. # You could say this is the main program - this runs the social media monitor screen and data                              #
  188. # The while loop uses 'while 1' - which means this will loop forever until I stop it                                       #
  189. # An important part is 'if time.time() >= timelastchecked:'                                                                #
  190. # This says "if the current time is greater than equal to the 'timelastchecked' then run                                   #
  191. # Every time our while loop cycles, it adds 45 seconds to 'timelastchecked' - by running 'timelastchecked = time.time()+45 #
  192. # This means time.time won't be greater or equal to 'timelastchecked' until 45 seconds has passed                          #
  193. #                                                                                                                          #
  194. ############################################################################################################################
  195.  
  196. while 1:
  197.     if time.time() >= timelastchecked: # Explained above...
  198.    
  199.         # Add 45 seconds to 'timelastchecked' - makes the while loop only run every 45 seconds. We don't need more frequent updates than that.
  200.         timelastchecked = time.time()+45
  201.        
  202.         #######################################################################
  203.         # SET UP THE STATIC SCREEN ELEMENTS - BACKGROUND, HEADINGS AND IMAGES #
  204.         #######################################################################
  205.        
  206.         # Set the background colour and border colour
  207.         screen.fill(black)
  208.         pygame.draw.rect(screen, black, (0,0,320,240),1) # Draw a rectangle (Surface, color, Rect, width)
  209.  
  210.         # load the social icon box image and place into position required
  211.         logo=pygame.image.load("socialmediabox.png") # Logo image to load (must be in same directory as this script)
  212.         screen.blit(logo,(210,40)) # Position of the logo on the screen - numbers are distance from left then top (left,top)       
  213.  
  214.         # Set the Twitter heading text
  215.         label=font.render("Twitter", 1, (gold)) # define exit message and colour
  216.         screen.blit(label,(5,40)) # Blits this new label onto the screen - numbers are distance from left then top (left,top)
  217.        
  218.         # Set the Facebook heading text
  219.         label=font.render("Facebook", 1, (gold))
  220.         screen.blit(label,(5,105))
  221.        
  222.         # Set the Google+ heading text
  223.         label=font.render("Google+", 1, (gold)) # define exit message and colour
  224.         screen.blit(label,(5,150)) # Blits this new label onto the screen - numbers are distance from left then top (left,top)
  225.        
  226.         # Set the Pinterest heading text
  227.         label=font.render("Pinterest", 1, (gold)) # define exit message and colour
  228.         screen.blit(label,(5,195)) # Blits this new label onto the screen - numbers are distance from left then top (left,top)
  229.        
  230.         ###########################################################################
  231.         # RUN A COMMAND TO GRAB THE PI TEMPERATURE                                #
  232.         #                                                                         #
  233.         # os.popen runs a command like you would in terminal                      #
  234.         # Try '/opt/vc/bin/vcgencmd measure_temp' in terminal to see for yourself #
  235.         # 'f' is a new line with the output of that command, which we will use    #
  236.         #                                                                         #
  237.         ###########################################################################
  238.        
  239.         f=os.popen("/opt/vc/bin/vcgencmd measure_temp")
  240.        
  241.         #######################################################################
  242.         # READ OUR NEW LINE AND MANIPULATE INTO A LABEL FOR OUT GUI           #
  243.         #                                                                     #
  244.         # We make a new empty string called 'mytemp'                          #
  245.         # We add the temperature line to this string                          #
  246.         # We then chop off characters from the front and back                 #
  247.         # We then set a font and colour for our PyGame label                  #
  248.         # After this, we make our 'mytemp' string the label text              #
  249.         # Finally, we 'blit' this to the screen (blit - to paste, add, paint) #
  250.         #                                                                     #
  251.         #######################################################################
  252.        
  253.         for i in f.readlines(): # Read the lines of 'f' - our temperature command output
  254.             mytemp = "" # Create an empty string called 'mytemp'
  255.             mytemp += i  # Add the temperature command line to our empty string
  256.             mytemp = mytemp[5:-1] # Cut 5 characters from the front of our string, and 1 from the rear
  257.             font2=pygame.font.Font(None,18) # Setting a custom font for the temp (font2)
  258.             label=font2.render(mytemp, 1, (grey)) # Make our 'mytemp' string the label text for PyGame
  259.             screen.blit(label,(280,5)) # Blits this new label onto the screen - numbers are distance from left then top (left,top)
  260.            
  261.             #########################################################################
  262.             # RUN A COMMAND TO GRAB THE TIME                                        #
  263.             #                                                                       #
  264.             # os.popen runs a command like you would in terminal                    #
  265.             # Try 'date' in termianl to see for yourself                            #
  266.             # 'f' is a new line with the output of that command, which we will use  #
  267.             #                                                                       #
  268.             #########################################################################
  269.            
  270.             f=os.popen("date")
  271.            
  272.             #############################################################################################
  273.             # SAME AS WITH THE TEMPERATURE COMMAND                                                      #
  274.             #                                                                                           #
  275.             # Read it, make it a string, chop it down, set the font, make the label then blit the label #
  276.             #                                                                                           #
  277.             #############################################################################################
  278.            
  279.             for i in f.readlines():  
  280.                 mytime = ""
  281.                 mytime += i  
  282.                 mytime = mytime[4:-13]  
  283.                 font3=pygame.font.Font(None,36)
  284.                 label=font3.render(mytime, 1, (white))
  285.                 screen.blit(label,(5,1))
  286.  
  287.                 ######################################################################################################################
  288.                 # GRAB TWITTER DATA USING URLLIB2                                                                                    #
  289.                 #                                                                                                                    #
  290.                 # Here we go to a URL and get our Pi to look for a line in the source code containing a certain string               #
  291.                 # This string has to be unique to this line or it will pull back multiple lines                                      #
  292.                 # The line we want is the line containing the data required, such as Twitter follower count                          #
  293.                 # Go to your public Twitter profile (logged out) and view the source                                                 #
  294.                 # Search for your number of Twitter followers using ctrl+f                                                           #
  295.                 # When you fine that number in the lines of code, find a unique string of text in that line that contains the data   #
  296.                 # Use that unique string below                                                                                       #
  297.                 # You will need to cut away the rest of that line in the code below, leaving you with just the data you want to see  #
  298.                 # Paste your unwanted characters into http://www.lettercount.com/ to count them for you                              #
  299.                 # ****NOTE If the site changes its layout or source code, things can move, and you will have to find this again****  #
  300.                 #                                                                                                                    #
  301.                 ######################################################################################################################
  302.            
  303.                 someurl= 'https://twitter.com/AverageManvsPi' # Set the URL for the Pi to look in to
  304.                 req = Request(someurl) # Request the URL
  305.                 try:
  306.                     response = urlopen(req)
  307.                 except URLError as e: #This section (307-317) is for error handling, showing "No connection" where a connection could not be made
  308.                     if hasattr(e, 'reason'):
  309.                         print 'We failed to reach a server.'
  310.                         print 'Reason: ', e.reason
  311.                         label=font.render("No Connection (1)", 1, (red))
  312.                         screen.blit(label,(5,60))
  313.                     elif hasattr(e, 'code'):
  314.                         print 'The server couldn\'t fulfill the request.'
  315.                         print 'Error code: ', e.code
  316.                         label=font.render("No Connection (2)", 1, (red))
  317.                         screen.blit(label,(5,60))
  318.                 else: # "If there are no errors and the connection is good"
  319.                     followcount = response.readlines() # read the lines of the URL and set these as a new string 'followcount'
  320.                     for line in followcount: # For statement
  321.                         if ' Followers"' in line: # If the Pi finds this string in the line...
  322.                             followcount = line[158:-32] # Take that line and cut away 158 characters from the front and 32 from the rear
  323.                             followcount = "Followers: " + followcount # Add text to the front of our data
  324.                             label=font.render(followcount, 1, (white)) # Make our 'followcount' string the label text for PyGame
  325.                             screen.blit(label,(5,60)) # Blits this new label onto the screen - numbers are distance from left then top (left,top)
  326.                            
  327.                         #########################################################################################################
  328.                         # RUNS ANOTHER QUERY ON THE SAME TWITTER URL IN THE SAME WAY - MAKES A SECOND LABEL WITH DIFFERENT DATA #
  329.                         #                                                                                                       #
  330.                         # This grabs my Twitter count of people that I follow                                                   #
  331.                         #                                                                                                       #
  332.                         #########################################################################################################
  333.                        
  334.                         if ' Following"' in line:
  335.                             tweetfollowing = line[158:-32]
  336.                             tweetfollowing = "Following: " + tweetfollowing
  337.                             label=font.render(tweetfollowing, 1, (white))
  338.                             screen.blit(label,(5,80))
  339.                    
  340.                             ###########################################################
  341.                             # NOW FACEBOOK DATA IN THE SAME WAY AS WE DID FOR TWITTER #
  342.                             ###########################################################
  343.                    
  344.                             someurl2= 'http://www.likealyzer.com/facebook/averagemanvspi'  
  345.                             req = Request(someurl2)  
  346.                             try:
  347.                                 response = urlopen(req)
  348.                             except URLError as e:
  349.                                 if hasattr(e, 'reason'):
  350.                                     print 'We failed to reach a server.'
  351.                                     print 'Reason: ', e.reason
  352.                                     label=font.render("No Connection (3)", 1, (red))
  353.                                     screen.blit(label,(5,125))
  354.                                 elif hasattr(e, 'code'):
  355.                                     print 'The server couldn\'t fulfill the request.'
  356.                                     print 'Error code: ', e.code
  357.                                     label=font.render("No Connection (4)", 1, (red))
  358.                                     screen.blit(label,(5,125))
  359.                             else:                          
  360.                                 fblikes = response.readlines()
  361.                                 for line in fblikes:
  362.                                     if 'Likes:' in line:
  363.                                         fblikes = line[75:-8]
  364.                                         fblikes = "Facebook Likes: " + fblikes
  365.                                         label=font.render(fblikes, 1, (white))
  366.                                         screen.blit(label,(5,125))
  367.                                
  368.                                         ##########################################
  369.                                         # NOW GOOGLE+ DATA IN THE SAME WAY AGAIN #
  370.                                         ##########################################
  371.                                
  372.                                         someurl3= 'https://plus.google.com/+AverageManvsPi/posts'  
  373.                                         req = Request(someurl3)  
  374.                                         try:
  375.                                             response = urlopen(req)
  376.                                         except URLError as e:
  377.                                             if hasattr(e, 'reason'):
  378.                                                 print 'We failed to reach a server.'
  379.                                                 print 'Reason: ', e.reason
  380.                                                 label=font.render("No Connection (5)", 1, (red))
  381.                                                 screen.blit(label,(5,170))
  382.                                             elif hasattr(e, 'code'):
  383.                                                 print 'The server couldn\'t fulfill the request.'
  384.                                                 print 'Error code: ', e.code
  385.                                                 label=font.render("No Connection (6)", 1, (red))
  386.                                                 screen.blit(label,(5,170))
  387.                                         else:          
  388.                                             gpluslikes = response.readlines()
  389.                                             for line in gpluslikes:
  390.                                                 if '</span> followers<span class' in line:
  391.                                                     gpluslikes = line[6802:-4444]
  392.                                                     gpluslikes = "Google+ Followers: " + gpluslikes
  393.                                                     label=font.render(gpluslikes, 1, (white))
  394.                                                     screen.blit(label,(5,170))
  395.                                        
  396.                                                     #########################################################################
  397.                                                     # FINALLY, GRAB PINTEREST DATA AND CREATE A LABEL IN THE SAME WAY AGAIN #
  398.                                                     #########################################################################
  399.                                        
  400.                                                     someurl4= 'https://uk.pinterest.com/averagemanvspi/'  
  401.                                                     req = Request(someurl4)  
  402.                                                     try:
  403.                                                         response = urlopen(req)
  404.                                                     except URLError as e:
  405.                                                         if hasattr(e, 'reason'):
  406.                                                             print 'We failed to reach a server.'
  407.                                                             print 'Reason: ', e.reason
  408.                                                             label=font.render("No Connection (7)", 1, (red))
  409.                                                             screen.blit(label,(5,215))
  410.                                                         elif hasattr(e, 'code'):
  411.                                                             print 'The server couldn\'t fulfill the request.'
  412.                                                             print 'Error code: ', e.code
  413.                                                             label=font.render("No Connection (8)", 1, (red))
  414.                                                             screen.blit(label,(5,215))
  415.                                                     else:  
  416.                                                         ytsubs = response.readlines()
  417.                                                         for line in ytsubs:
  418.                                                             if 'name="pinterestapp:followers"' in line:
  419.                                                                 ytsubs = line[91:-12]
  420.                                                                 ytsubs = "Pinterest Followers: " + ytsubs
  421.                                                                 label=font.render(ytsubs, 1, (white))
  422.                                                                 screen.blit(label,(5,215))
  423.                                
  424.     #########################################################################################
  425.     # SOME HANDY DEBUGGING CODE THAT WILL PRINT INFO TO TERMINAL WHEN THE SCREEN IS TOUCHED #
  426.     #########################################################################################
  427.    
  428.     for event in pygame.event.get():
  429.         if event.type == pygame.MOUSEBUTTONDOWN:
  430.             print "screen pressed" # Tells us when the screen detects a press
  431.             pos = (pygame.mouse.get_pos() [0], pygame.mouse.get_pos() [1])
  432.             print pos # Prints the position of the press
  433.             pygame.draw.circle(screen, white, pos, 2, 0) # Adds a small dot where the screen is pressed
  434.             on_click()
  435.  
  436.         ######################################################
  437.         # A WAY TO EXIT THE PROGRAM IF THE TOUCHSCREEN FAILS #
  438.         ######################################################
  439.        
  440.         if event.type == KEYDOWN:
  441.             if event.key == K_ESCAPE:
  442.                 sys.exit()
  443.                
  444.     #########################################################################################################################
  445.     # UPDATE THE DISPLAY - A VITAL PIECE OF THE CODE INCLUDED IN THE WHILE STATEMENT - WITHOUT, THE SCREEN WOULD NOT CHANGE #
  446.     #########################################################################################################################
  447.    
  448.     pygame.display.update()
RAW Paste Data