Sugree

skip to navigation

Fixed noknok.py

โค้ดคราวที่แล้วมีบั๊ก มีคนเจอด้วย นิดหน่อย ตกไปสองบรรทัด

diff --git a/noknok.py b/noknok.py
index 82e260f..8c30159 100644
--- a/noknok.py
+++ b/noknok.py
@@ -199,6 +199,8 @@ Commands:
         runonce(self.nok, q, eval(query), since_id,self._save_since_id)
 
     def _save_since_id(self, since_id):
+        if not self.conf.has_section('twitter'):
+            self.conf.add_section('twitter')
         self.conf.set('twitter', 'since_id', str(since_id))
         self.conf.write(open(self.options.config, 'w'))

ถ้าไม่ได้สร้างไฟล์ noknok.conf ไว้ตั้งแต่แรกก็อาจจะเจอปัญหาเล็กๆ น้อยๆตอนพยายามเขียน

เจออีกตัว

diff --git a/noknok.py b/noknok.py
index 8c30159..f7bb15a 100644
--- a/noknok.py
+++ b/noknok.py
@@ -151,7 +151,7 @@ Commands:
             command = self.args[0]
         else:
             command = 'twitterforever'
-        method = getattr(self, 'do_%s' % self.args[0])
+        method = getattr(self, 'do_%s' % command)
         if not method:
             print 'unknown command'
             return

แก้แล้วโค้ดออกมาแบบนี้

#!/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' % command)
        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):
        if not self.conf.has_section('twitter'):
            self.conf.add_section('twitter')
        self.conf.set('twitter', 'since_id', str(since_id))
        self.conf.write(open(self.options.config, 'w'))
 
if __name__ == '__main__':
    app = App()
    app.run()

NokNok ควรจะมี API ได้แล้วนะ

Submitted by sugree on Mon, 07/14/2008 - 09:03

เย้..

เย้.. ใช้ได้แล้ว ขอบคุณค่าาา

I think this line: method =

I think this line:

method = getattr(self, 'do_%s' % self.args[0])

should be changed to

method = getattr(self, 'do_%s' % command)

อ๊ากใช่

อ๊ากใช่

ว่าแล้ว

ว่าแล้ว อิอิ ขอบคุณมากครับสำหรับ bug fixed

Post new comment

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

Main menu

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