Sugree

skip to navigation

Following all followers in NokNok

สคริปต์ noknok.py เมื่อวันก่อนทำเอาหลายคนกลายเป็นสแปม เพราะพยายามจะเอาไปรันใน cron ยกตัวอย่างเช่น @pruet คราวนี้เลยแก้ตัวใหม่ ใส่ไฟล์คอนฟิกให้อันนึง อย่างน้อยก็เอาไว้เก็บว่าเคย sync ถึงไหนแล้ว และแถมด้วยการติดตามเพื่อนทุกคนของคนที่ต้องการ

เนื่องจาก NokNok ยังไม่มี APIs ผมก็ขี้เกียจทำ regexp สุดท้ายเลยตัดสินใจใช้ XPath ของ lxml ซะเลย ดูเหมือนว่าจะไม่มี lxml บนวินโดส์ ยังไม่รู้จะแก้ปัญหาให้ยังไง คำแนะนำตอนนี้คือ ลงลินุกซ์

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
 
from urllib import urlencode
from urllib2 import urlopen, HTTPCookieProcessor, build_opener, install_opener, Request
import re
import os
import getpass
from optparse import OptionParser
from ConfigParser import ConfigParser
 
import simplejson
 
cookie_processor = HTTPCookieProcessor()
opener = build_opener(cookie_processor)
install_opener(opener)
 
user_agent = 'noknok'
 
def confopt(conf, section, option, default=None):
    try:
        return conf.get(section, option)
    except:
        return default
 
def user_timeline(u, since_id=0):
    url = 'http://twitter.com/statuses/user_timeline/%s.json' % u
    data = {}
    if since_id > 0:
        data['since_id'] = since_id
    req = Request(url,
                  urlencode(data),
                  {'User-Agent': user_agent})
    fd = urlopen(req)
    results = simplejson.loads(fd.read())
    return filter(lambda x: x['id'] > since_id, results)
 
def summize(q, since_id=0):
    url = 'http://summize.com/search.json'
    req = Request(url,
                  urlencode({'q': q, 'since_id': since_id}),
                  {'User-Agent': user_agent})
    fd = urlopen(req)
    results = simplejson.loads(fd.read())['results']
    return results
 
class NokNok:
 
    url = 'http://www.noknok.in.th/'
 
    def __init__(self, username, password):
        self.username = username
        self.password = password
 
    def home(self):
        url = self.url+'myhome'
        fd = urlopen(url)
        fd.read()
 
    def login(self):
        #print 'logging in'
        url = self.url+'login/'
        fd = urlopen(url, urlencode({'username': self.username,
                                     'password': self.password,
                                     'remember_me': '1'}))
        content = fd.read()
        if fd.code != 200:
            print code, content
        #print fd.headers
        #print content
 
    def post(self, msg):
        #print 'posting %s' % msg
        url = self.url+'message/add'
        req = Request(url, urlencode({'msg_update': msg.encode('utf-8')}), {'Referer': self.url+'myhome'})
        fd = urlopen(req)
        content = fd.read()
        #print fd.headers
        #print content
        if fd.code != 200:
            print code, content
 
    def get_followers(self, user=None):
        from lxml import etree as ET
 
        user = user or self.username
        url = self.url+user+'/followers'
        followers = []
        while 1:
            fd = urlopen(url)
            content = fd.read()
            tree = ET.HTML(content.decode('utf-8'))
            node = tree.xpath("//ul[@class='list_friends_follow']")[0]
            for item in node:
                d = {'screen_name': item.findtext('h3'),
                     'links': {}}
                links = item.xpath('./ul/li[3]/span/a')
                for i in links:
                    title = i.attrib['title']
                    if title == u'ติดตาม':
                        d['links']['follow'] = i.attrib['href']
                    elif title == u'บล็อค':
                        d['links']['block'] = i.attrib['href']
                followers.append(d)
            next = tree.xpath("//span[@class='next-page']")[0].find('a')
            if next is None:
                break
 
            url = next.attrib['href']
        return followers
 
def runonce(nok, q, query, since_id=0, cb_save=None):
    try:
        results = query(q, since_id=since_id)
    except Exception, why:
        print why
        results = []
    results.reverse()
    for item in results:
        nok.post(item['text'])
        since_id = item['id']
    if cb_save:
        cb_save(since_id)
    return since_id
 
def run(nok, q, query, since_id=0, interval=30, cb_save=None):
    import time
 
    if since_id == 0:
        since_id = query(q)[0]['id']
    while 1:
        since_id = runonce(nok, q, query, since_id, cb_save)
        time.sleep(interval)
 
class App:
    def __init__(self):
        usage = '''usage: %prog [options] followall|twitteronce|twitterforever
 
Commands:
  followall [screen_name]
  twitteronce
  twitterforever'''
        parser = OptionParser(usage=usage)
        parser.add_option('-c', '--config',
                          default='noknok.cfg', dest='config',
                          help='configuration file')
        self.options, self.args = parser.parse_args()
 
    def run(self):
        if len(self.args) > 0:
            command = self.args[0]
        else:
            command = 'twitterforever'
        method = getattr(self, 'do_%s' % self.args[0])
        if not method:
            print 'unknown command'
            return
 
        self.conf = ConfigParser()
        self.conf.read([self.options.config, 'noknok.cfg', os.path.expanduser('~/.noknok.cfg')])
 
        username = confopt(self.conf, 'noknok', 'username')
        if username is None:
            username = raw_input('noknok user: ')
        password = confopt(self.conf, 'noknok', 'password')
        if password is None:
            password = getpass.getpass('noknok password: ')
        self.nok = NokNok(username, password)
        self.nok.login()
 
        return method()
 
    def do_followall(self):
        if len(self.args) > 1:
            user = self.args[1]
        else:
            user = self.nok.username
        for user in self.nok.get_followers(user):
            if 'follow' in user['links']:
                print 'following %s' % user['screen_name']
                fd = urlopen(user['links']['follow'])
                fd.read()
 
    def do_twitterforever(self):
        q = confopt(self.conf, 'twitter', 'query')
        if q is None:
            q = raw_input('twitter user: ')
        query = confopt(self.conf, 'twitter', 'source', 'user_timeline')
        since_id = int(confopt(self.conf, 'twitter', 'since_id', '0'))
        interval = int(confopt(self.conf, 'twitter', 'interval', '30'))
        run(self.nok, q, eval(query), since_id, interval, self._save_since_id)
 
    def do_twitteronce(self):
        q = confopt(self.conf, 'twitter', 'query')
        if q is None:
            q = raw_input('twitter user: ')
        query = confopt(self.conf, 'twitter', 'source', 'user_timeline')
        since_id = int(confopt(self.conf, 'twitter', 'since_id', '0'))
        runonce(self.nok, q, eval(query), since_id,self._save_since_id)
 
    def _save_since_id(self, since_id):
        self.conf.set('twitter', 'since_id', str(since_id))
        self.conf.write(open(self.options.config, 'w'))
 
if __name__ == '__main__':
    app = App()
    app.run()

ยาวขึ้นเยอะเหมือนกัน คราวนี้ฉลาดขึ้น ควรใช้ไฟล์คอนฟิกให้เป็นประโยชน์ด้วย หน้าตาประมาณนี้

[twitter]
source = user_timeline
since_id = 0
query = sugree
 
[noknok]
username = sugree
password = xxxxxx

ถ้าอยากใช้ summize ก็แก้ตรง source วางไฟล์นี้ไว้ที่เดียวกับ noknok.py หรือจะไว้ที่ ~/.noknok.py ก็ด้ ตอนนี้มี 3 คำสั่ง

python noknok.py twitterforever

อันนี้ทำเหมือนรุ่นเก่า รันไปเรื่อย

python noknok.py twitteronce

จะอ่านรอบเดียว ส่งรอบเดียว

python noknok.py followall

ค้นหาว่าใครที่ติดตามเราแล้วเรายังไม่ได้ติดตามกลับ ก็ติดตามซะ

python noknok.py followall sugree

แบบนี้จะติดตามทุกคนที่ติดตาม sugree กรุณาใช้ด้วยความระวัง

เตือนแล้วนะ_

ว่าแล้วก็เตรียมทำ python-noknok ดีกว่า

Submitted by sugree on Thu, 07/10/2008 - 00:12

Great work, my master.

Great work, my master.

Works like a charm on Cygwin

Works like a charm on Cygwin (I mean, on Windows)

:)

ตั้งโต๊ะล

ตั้งโต๊ะลง linux กันดีกว่า สร้าง factor ให้คนจำต้องใช้แบบนี้เยอะๆ แล้วก็นัดกัน ยกโน้ตบุ๊กมาหักดิบลง linux กันเลย

เอา mac

เอา mac มาลงก่อนเลย

T_T" copy

T_T" copy ไปแปะเลยไม่ได้เหรอ? ลอง copy จากกล่องใหญ่ๆ แล้วมันเปิดไม่ได้.. (ประจำ.. ลองอะไรแล้วได้เรื่องประจำเลย)

อ๊าาาาาาาาาา ทำไม ทำไม

ถ้าอ่านแล

ถ้าอ่านแล้วทำตามได้เมื่อไหร่จะให้ประกาศนียบัตร

Work great on my hardy.

Work great on my hardy.

Post new comment

The content of this field is kept private and will not be shown publicly.
+

Main menu

+++++++++++++++++++++++++++++++