source: trollforge/dsp-trollforge/MovableType/Mtpost.py @ 212

Revision 41, 4.3 KB checked in by sam, 8 years ago (diff)
  • DSP's trollforge snapshot.
  • Property svn:executable set to *
  • Property svn:keywords set to Id
Line 
1#!/usr/bin/env python
2#
3# mt-post.py:
4#   Post a comment on any MT blog entry. Also defeats stupid SCode "security"
5#   check that is so annoying when using a text browser.
6#
7# Usage:
8#   mt-post.py "blog_entry_url" "nick" "valid@email.com" "multi\nline\ncomment"
9#
10# Copyright: (c) 2004 Sam Hocevar <sam@zoy.org>
11#   This program is free software; you can redistribute it and/or
12#   modify it under the terms of the Do What The Fuck You Want To
13#   Public License as published by Banlu Kemiyatorn. See
14#   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
15#
16
17import gd, urllib, urllib2, sys, re
18
19# Behave nicely, like MSIE
20user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)"
21
22# Guess a glyph from its bounding box in the picture. This function is very,
23# very naive. But since mt-scode is very, very naive as well, it's more than
24# enough.
25def guess_glyph(im, xmin, xmax, ymin, ymax):
26    values = [162, 131, 150, 139, 155, 159, 181, 90, 180, 170]
27    count = 0
28    for x in range(xmin, xmax):
29        for y in range(ymin, ymax):
30            count += im.getPixel((x,y)) * (y - ymin)
31    if count not in values:
32        return "?"
33    return values.index(count)
34
35# Remove background stuff from an scode picture
36def remove_background(im):
37    (w,h) = im.size()
38    # Stats on first 3 lines to determine background colours
39    stats = [0, 0, 0, 0]
40    fg = 0
41    bg = 0
42    for y in range(3):
43        for x in range(w):
44            p = im.getPixel((x,y))
45            if p < 4:
46                stats[p] += 1
47    for i in range(1,4):
48        if stats[i] < stats[fg]:
49            fg = i
50        if stats[i] > stats[bg]:
51            bg = i
52    # Unify background colours
53    for y in range(h):
54        for x in range(w):
55            p = im.getPixel((x,y))
56            if p == fg:
57                im.setPixel((x,y),1)
58            else:
59                im.setPixel((x,y),0)
60
61# Decode an scode picture from its URL
62def sdecode(url):
63    r = urllib2.Request(url)
64    r.add_header('User-Agent', user_agent)
65    f = urllib2.build_opener().open(r)
66    im = gd.image(f, "png")
67    (w,h) = im.size()
68    f.close()
69    remove_background(im)
70    # Find ymin/ymax bounding box
71    ymin = -1
72    ymax = -1
73    for y in range(h):
74        found = 0
75        for x in range(w):
76            p = im.getPixel((x,y))
77            if p == 1:
78                found = 1
79                break
80        if found:
81            if ymin == -1:
82                ymin = y
83            else:
84                ymax = y + 1
85    # Read character cells
86    result = ""
87    incell = 0
88    for x in range(w):
89        found = 0
90        for y in range(ymin, ymax):
91            p = im.getPixel((x,y))
92            if p == 1:
93                found = 1
94                break
95        if found and not incell:
96            incell = 1
97            xmin = x
98        if not found and incell:
99            incell = 0
100            result += str(guess_glyph(im, xmin, x, ymin, ymax))
101    return result
102
103def mt_post(url, nick, email, comment):
104    data = {}
105    re_scode = re.compile('.*src="([^"]*mt-scode[^"]*)".*\n')
106    re_action = re.compile('.*action="([^"]*mt-comments[^"]*)".*\n')
107    re_hidden = re.compile('.*type="hidden".*name="([^"]*)".*value="([^"]*)".*\n')
108    r = urllib2.Request(url)
109    r.add_header('User-Agent', user_agent)
110    f = urllib2.build_opener().open(r)
111    while True:
112        l = f.readline()
113        if not l:
114            break
115        # Detect an scode token
116        m = re_scode.match(l)
117        if m:
118            scode = sdecode(m.group(1))
119            data['scode'] = scode
120        # Detect a hidden input
121        m = re_hidden.match(l)
122        if m:
123            data[m.group(1)] = m.group(2)
124        # Find the form target
125        m = re_action.match(l)
126        if m:
127            target = m.group(1)
128    f.close()
129    data['author'] = nick
130    data['email'] = email
131    data['text'] = comment
132    data['post'] = "yes"
133    r = urllib2.Request(target, urllib.urlencode(data))
134    r.add_header('User-Agent', user_agent)
135    f = urllib2.build_opener().open(r)
136    while True:
137        l = f.readline()
138        if not l:
139            break
140    f.close()
141
142mt_post(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
Note: See TracBrowser for help on using the repository browser.