root/branches/pluggable-contents/blog/receivers.py

Revision 67, 6.0 kB (checked in by nobu, 8 months ago)

pluggable-contents:

Line 
1 # vim: encoding=utf-8 :
2
3 import httplib
4 import re
5 import urllib
6 import urlparse
7 from threading import Thread
8 import xmlrpclib
9
10 from django.conf import settings
11 from django.contrib.sitemaps import ping_google
12 from django.contrib.sites.models import Site
13 from django.core.mail import mail_admins
14 from django.template import loader, Context
15 from django.utils.translation import ugettext as _
16 from django.template.defaultfilters import striptags
17 from markup.templatetags.markup import restructuredtext as rest
18
19 try:
20     import twitter
21     has_twitter = True
22 except ImportError:
23     has_twitter = False
24
25 URL_PATTERN = re.compile(r'https?://[-_0-9a-zA-Z./?&;]+')
26
27
28 def run_ping_google():
29     """
30     send google ping.
31     """
32     try:
33         ping_google('/sitemap.xml')
34     except Exception, e:
35         #mail_admins(_(u'[Google Sitemap] Caught exception.'), str(e))
36         pass
37
38
39 def run_post_twitter(url):
40     """
41     post to twitter.
42     """
43     try:
44         username = getattr(settings, 'TWITTER_USERNAME', None)
45         password = getattr(settings, 'TWITTER_PASSWORD', None)
46         api = twitter.Api(username=username, password=password)
47         api.PostUpdate(_(u'Updated my blog!\n%s') % url)
48     except Exception, e:
49         #mail_admins(_(u'[Twitter] Caught exception.'), str(e))
50         pass
51
52
53 def run_update_ping(server, title, url):
54     """
55     send update ping.
56     """
57     try:
58         server.weblogUpdates.ping(title, url)
59     except:
60         pass
61
62
63 class TrackBackPingThread(Thread):
64     """
65     send track back ping.
66     """
67     def __init__(self, target, url, blog_name, title, excerpt):
68         self.target = target
69         self.url = url
70         self.blog_name = blog_name
71         self.title = title
72         self.excerpt = excerpt
73         super(TrackBackPingThread, self).__init__()
74
75     def run(self):
76         trackback_url = self.get_trackback_url()
77         if trackback_url is None:
78             return None
79         params = urllib.urlencode({
80             'url': self.url,
81             'blog_name': self.blog_name,
82             'title': self.title,
83             'excerpt': self.excerpt,
84         })
85         headers = ({
86             'Content-type': 'application/x-www-form-urlencoded',
87         })
88         parsed = urlparse.urlparse(trackback_url)
89         host, path = parsed[1:3]
90         conn = httplib.HTTPConnection(host)
91         conn.request("POST", path, params, headers)
92         conn.getresponse()
93         conn.close()
94
95     def get_trackback_url(self):
96         parsed = urlparse.urlparse(self.target)
97         host, path = parsed[1:3]
98         try:
99             conn = httplib.HTTPConnection(host)
100             conn.request("GET", path)
101             res = conn.getresponse().read()
102         except:
103             return None
104         ptn1 = r'trackback:ping="(https?://%s.*?)"' % host
105         if not path.endswith('/'):
106             path += '/'
107         ptn2 = r'(https?://%s%strackback/?)' % (host, path)
108         for p in (ptn1, ptn2):
109             try:
110                 return re.search(p, res).group(1)
111             except:
112                 pass
113
114
115 def post_save_entry(instance, created, raw, **kwargs):
116     """
117     blog.models.Entry post save hook.
118     """
119     if settings.DEBUG or raw or not hasattr(instance, 'published_now'):
120         return
121     current_site = Site.objects.get_current()
122     site_name = current_site.name
123     site_url = u'http://%s/' % current_site.domain
124     detail_url = u'http://%(domain)s%(path)s' % {
125         'domain': current_site.domain,
126         'path': instance.get_absolute_url(),
127     }
128
129     #   send google webmaster.
130     Thread(target=run_ping_google).start()
131     #   send twitter.
132     if has_twitter:
133         Thread(target=run_post_twitter, args=[detail_url]).start()
134     #   send update ping.
135     xmlrpclib.Transport.user_agent = current_site.domain
136     from blog.models import PingServer
137     for ping in PingServer.objects.filter(is_active__exact=True):
138         server = xmlrpclib.Server(ping.get_absolute_url())
139         Thread(target=run_update_ping, args=[server, site_name, site_url]).start()
140     target_list = URL_PATTERN.findall(instance.description)
141     if not len(target_list):
142         return
143     #   send track back ping
144     blog_name = site_name.encode('utf-8')
145     title = instance.title.encode('utf-8')
146     excerpt = striptags(rest(instance.description))[:200].encode('utf-8')
147     for target in target_list:
148         TrackBackPingThread(target=target, url=detail_url, blog_name=blog_name,
149                             title=title, excerpt=excerpt).start()
150
151
152 def post_save_comment(instance, created, raw, **kwargs):
153     """
154     blog.models.Comment post save hook.
155     """
156     #   increment parent comments count if created.
157     if created:
158         instance.entry.comments_count += 1
159         instance.entry.save_base()
160
161     #   nothing to do if raw save or updated.
162     if raw or not created:
163         return
164
165     #   send mail to admins.
166     c = Context({
167         'obj': instance,
168         'site': Site.objects.get_current(),
169     })
170     t = loader.get_template('blog/add_comment_mail.txt')
171     mail_admins(_(u'new comment has been added.'), t.render(c))
172
173
174 def pre_delete_comment(instance):
175     """
176     blog.models.Comment pre delete hook.
177     """
178     entry = instance.entry
179     if entry.comments_count > 0:
180         entry.comments_count -= 1
181         entry.save_base()
182
183
184 def post_save_trackback(instance, created, raw, **kwargs):
185     """
186     blog.models.TrackBack post save hook.
187     """
188     #   increment parent comments count if created.
189     if created:
190         instance.entry.trackbacks_count += 1
191         instance.entry.save_base()
192
193     #   nothing to do if raw save or updated.
194     if raw or not created:
195         return
196
197     #   send mail to admins.
198     c = Context({
199         'obj': instance,
200         'site': Site.objects.get_current(),
201     })
202     t = loader.get_template('blog/add_trackback_mail.txt')
203     mail_admins(_(u'new track back has been added.'), t.render(c))
204
205
206 def pre_delete_trackback(instance):
207     """
208     blog.models.Comment pre delete hook.
209     """
210     entry = instance.entry
211     if entry.trackbacks_count > 0:
212         entry.trackbacks_count -= 1
213         entry.save_base()
Note: See TracBrowser for help on using the browser.