PythonRéseau socialweb2

Twittez sans être derrière votre écran

J’ai découvert il y a peu de temps la librairie python-twitter qui permet de développer ses propres applications clientes twitter en python.

J’ai donc écrit un « bot » appelé twitter-tfa qui permet de programmer une série de tweets à publier.

Le principe est ultra simple : on lui donne en entrée une liste de tweets qu’il publie aléatoirement toutes les x minutes. Très pratique pour étaler ses publications sur twitters et préserver une « présence ».

En fait, il est même un peut plus intelligent que ça car il construit sa liste de tweets à publier de 2 manières :

  • d’abord à partir d’un fichier dans lequel on liste des tweets à publier, ainsi que leur occurrence (1 fois, 2 fois, etc) ;
  • ensuite, à partir d’un flux RSS, le bot créera seul les tweets correspondants aux articles les plus récents. Bien utile pour communiquer sur son blog (sans matraquage… ) !

Vous pouvez reprendre le code et l’adapter à vos besoins mais n’oubliez pas auparavant d’enregistrer votre application sous Twitter afin de compléter les clefs nécessaires dans le script (consumer key, access token, etc).

Voici un exemple du fichier de tweets que vous donnez en entrée :

1 Has Christine Lagarde got what it takes to head the IMF? | Philippe Marlière http://t.co/78RJzaZ via @guardian
1 In pictures: Ratko Mladic – career of a general on the run http://t.co/kDRKHe2 via @guardian
2 Facebook : pas d'enfants de moins de 13 ans... pour l'instant http://t.co/isBQBd8 via @Numerama
1 Des prisonniers chinois forcés à jouer à World of Warcraft http://t.co/wU46Qrg via @Numerama
1 Sécurité : une faille importante a été décelée sur LinkedIn | ITespresso.fr http://t.co/Y7FiMDS

Les chiffres devant les tweets sont le nombre d’occurence.

Voici le manuel du script :

TWITTER-TFA (c) Thomas Fauré  2011

Bot able to tweet.

Usage :

parameters:
--period=               : period, in minutes, between two tweets.
--file=                   : tweet file path to read
--feedurl=            : feed URL to consider
--feednumber=  : max item number considered in the given feed

options:
--simulation  : fake mode, to simulate.
--proxy       : to use a proxy.

Voici le code source :

#!/bin/env python
# -*- coding: utf-8 -*-
"""
TWITTER-TFA (c) Thomas Fauré <faure.thomas@gmail.com> 2011

Bot able to tweet.

Usage :

parameters:
--period=<period>               : period, in minutes, between two tweets.
--file=<file>                   : tweet file path to read
--feedurl=<feed url>            : feed URL to consider
--feednumber=<feed max number>  : max item number considered in the given feed

options:
--simulation  : fake mode, to simulate.
--proxy       : to use a proxy.
"""

import os,sys,twitter,urllib2,random,getopt,time,shutil
from getpass import getpass
from xml.dom import minidom

# PARAMETERS :
C__PERIOD = 5   # period in minutes
C__SUFFIX  = '' # tweet suffix
C__FEED    = 'http://blog.whibe.com/feed/'
C__FEED_BOUCLE = 1
C__FEED_NUMBER = 10
C__FILE    = 'tweets.txt'

# OPTIONS :
C__HORODATAGE = False # Pas encore implémenté
C__DOUBLONS   = False # Si False, il n'y aura pas de doublons émis
C__SIMULATION = False
C__PROXY      = False
C__BOUCLE     = True

try:
    opts, args = getopt.getopt(sys.argv[1:], '', ['period=', 'file=', 'doublons','simulation','proxy','feednumber=','feedurl='])
except getopt.GetoptError, err:
    # print help information and exit:
    print __doc__
    print str(err) # will print something like "option -a not recognized"
    sys.exit(2)
for o, a in opts:
    if o == "--period":
        C__PERIOD = int(a)
        print("PERIODE initialisée à %d."%C__PERIOD)
    elif o == "--feednumber":
        C__FEED_NUMBER = int(a)
        print("FEEDNUMBER initialisée à %d."%C__FEED_NUMBER)
    elif o == "--feedurl":
        C__FEED = a
        print("FEEDURL initialisé à %s."%C__FEED)
    elif o == "--file":
        C__FILE = a
        print("FILE initialisé à '%s'."%C__FILE)
    elif o == "--simulation":
        C__SIMULATION = True
        print("Mode SIMULATION activé.")
    elif o == "--doublons":
        C__DOUBLONS = True
        print("Mode DOUBLONS activé.")
    elif o == "--proxy":
        C__PROXY = True
        print("Mode PROXY activé.")
    else:
        assert False, "unhandled option"

C__CONSUMER_KEY       = 'xxxxxxxxxxxxxxxxxxxx'
C__CONSUMER_SECRET    = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
C__ACCESS_TOKEN_KEY   = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
C__ACCESS_TOKEN_SECRET= 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

# --- FUNCTIONS --------------------------------------------------------------------
def getText(nodelist):
    rc = []
    for node in nodelist:
        if node.nodeType == node.TEXT_NODE:
            rc.append(node.data)
    return ''.join(rc)

def Shorten(longURL):
    result = None
    f      = urllib2.urlopen("http://tinyurl.com/api-create.php?url=%s" % longURL)
    try:
        result = f.read()
    finally:
        f.close()
    return result

def rewriteFile(i__tweets,i__filename):
    file = open(i__filename,'wb')
    for tweet in i__tweets:
        file.write("%d %s\n"%(int(tweet[1]),tweet[0]))
    file.close()
# --- END FUNCTIONS ----------------------------------------------------------------

# --- Proxy management -------------------------------------------------------------
proxy = {}
if C__PROXY:
    proxypasswd = getpass('Proxy password: ')
    proxy_info = {
        'user' : 'yourusername',
        'pass' : proxypasswd,
        'host' : "yourproxyhost",
        'port' : 8080
    }
    proxy_string = "http://%(user)s:%(pass)s@%(host)s:%(port)d" % proxy_info
    if proxypasswd != '':
        proxy = {"http" : proxy_string,"https" : proxy_string}
        proxy_support = urllib2.ProxyHandler(proxy)
        opener = urllib2.build_opener(proxy_support, urllib2.HTTPHandler)
        urllib2.install_opener(opener)
# --- End of Proxy management -------------------------------------------------------

print
print('Création du dictionnaire de tweets')
print
tweets = []

def compute_tweet(i__text,i__link,i__suffix):
    o__tweet = i__text + ' ' + i__link + i__suffix
    if len(o__tweet) > 140:
        o__tweet = i__text[0:136-len(i__link)-len(i__suffix)] + '... ' + i__link + i__suffix
    return o__tweet
# --- Get tweets from a feed --------------------------------------------------------
if C__FEED != '':
    i = 0
    print C__FEED
    f = urllib2.urlopen(C__FEED)
    dom = minidom.parseString(f.read())
    channels = dom.getElementsByTagName("channel")
    for channel in channels:
        items = channel.getElementsByTagName("item")
        for item in items:
            text = getText(item.getElementsByTagName("title")[0].childNodes).encode('utf-8')
            link  = Shorten(getText(item.getElementsByTagName("link")[0].childNodes))
            tweet = compute_tweet(text,link,C__SUFFIX)
            print tweet,len(tweet),C__FEED_BOUCLE
            tweets.append( [tweet,C__FEED_BOUCLE] )
            i += 1
            if i >= C__FEED_NUMBER:
                break

# --- Get tweets from a file --------------------------------------------------------
if C__FILE != '':
    # create a working file :
    working_file = C__FILE + str(int(time.time()))
    os.system("cp %s %s"%(C__FILE,working_file))
    #~ shutil.copyfile(C__FILE,working_file)
    # process it
    file = open(working_file,'r')
    for line in file.readlines():
        line = line.strip()
        if line != '':
            tweet_boucle = 999
            if C__BOUCLE:
                tweet_boucle_str = line.split(' ')[0]
                tweet_boucle = int(tweet_boucle_str)
                line = line[len(tweet_boucle_str)+1:]
            tweet = line[0:140]
            print tweet,len(tweet),tweet_boucle
            if len(line) > 140:
                if raw_input("Le tweet ci-dessus contient plus que 140 caractères. Voulez-vous continuer ? (y/n) ") == 'n':
                    sys.exit(0)
            tweets.append( [tweet,tweet_boucle] )
    file.close()

print
print('%d tweets.'%len(tweets))
print

api = twitter.Api(
    consumer_key        = C__CONSUMER_KEY,
    consumer_secret     = C__CONSUMER_SECRET,
    access_token_key    = C__ACCESS_TOKEN_KEY,
    access_token_secret = C__ACCESS_TOKEN_SECRET,
    proxy = proxy
    )
i = 0
while len(tweets)>0:
    # check end :
    somme = 0
    for tweet in tweets:
        somme += tweet[1]
    if somme == 0:
        break
    i += 1
    randnumber = random.randint(0,len(tweets)-1)
    tweet = tweets[randnumber][0]
    tweet_boucle = tweets[randnumber][1]
    if tweet_boucle > 0:
        print time.asctime(time.localtime()),">>", str(i), ">>", tweet
        if not C__SIMULATION:
            try:
                api.PostUpdate(tweet)
            except:
                print 'Unable to tweet'
        print len(tweets)
        sum = 0
        for tweet in tweets:
            sum += tweet[1]
        print 'Rest =',sum
        tweets[randnumber][1] = tweet_boucle - 1
        if C__FILE != '':
            rewriteFile(tweets,working_file)
        time.sleep(C__PERIOD * 60)
print('End')
os.remove(working_file)
Related Posts with Thumbnails

Laisser une réponse

Connect with Facebook