From 92b2b34ccfd908295f8e93aa4728ad8eaa18bda0 Mon Sep 17 00:00:00 2001 From: "Christopher R. Gabriel" Date: Tue, 30 Mar 2010 11:37:27 +0200 Subject: added twitting support (e.g. for twitter/identi.ca) --- mini-dinstall | 37 +++++++++++++++++++++++++++++++- minidinstall/tweet.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 minidinstall/tweet.py diff --git a/mini-dinstall b/mini-dinstall index ddbc629..d80074c 100755 --- a/mini-dinstall +++ b/mini-dinstall @@ -33,6 +33,7 @@ from minidinstall.GPGSigVerifier import * from minidinstall.version import * import minidinstall.misc import minidinstall.mail +import minidinstall.tweet debchanges_re = re.compile('([-a-z0-9+.]+)_(.+?)_([-a-zA-Z0-9]+)\.changes$') debpackage_re = re.compile('([-a-z0-9+.]+)_(.+?)_([-a-zA-Z0-9]+)\.u?deb$') @@ -53,6 +54,7 @@ logfile_name = 'mini-dinstall.log' configfile_names = ['/etc/mini-dinstall.conf', '~/.mini-dinstall.conf'] use_dnotify = 0 mail_on_success = 1 +tweet_on_success = 1 default_poll_time = 30 default_max_retry_time = 2 * 24 * 60 * 60 default_mail_log_level = logging.ERROR @@ -62,6 +64,9 @@ mail_log_flush_count = 10 mail_to = getpass.getuser() mail_server = 'localhost' incoming_permissions = 0750 +tweet_server = 'identica' +tweet_user = None +tweet_password = None default_architectures = ["all", "i386"] default_distributions = ("unstable",) @@ -77,6 +82,8 @@ Changes: %(changes_without_dot)s """ +tweet_template = "Installed %(source)s %(version)s to %(distribution)s" + def usage(ecode, ver_only=None): print "mini-dinstall", pkg_version if ver_only: @@ -332,6 +339,15 @@ if configp.has_option('DEFAULT', 'mail_subject_template'): mail_subject_template = configp.get('DEFAULT', 'mail_subject_template', 1) if configp.has_option('DEFAULT', 'mail_body_template'): mail_body_template = configp.get('DEFAULT', 'mail_body_template', 1) +if configp.has_option('DEFAULT', 'tweet_template'): + tweet_template = configp.get('DEFAULT', 'tweet_template', 1) + +if configp.has_option('DEFAULT', 'tweet_server'): + tweet_server = configp.get('DEFAULT', 'tweet_server', 1) +if configp.has_option('DEFAULT', 'tweet_user'): + tweet_user = configp.get('DEFAULT', 'tweet_user', 1) +if configp.has_option('DEFAULT', 'tweet_password'): + tweet_password = configp.get('DEFAULT', 'tweet_password', 1) sects = configp.sections() if not len(sects) == 0: @@ -360,6 +376,7 @@ class DistOptionHandler: self._optionmap['chown_changes_files'] = ['bool', 1] self._optionmap['keep_old'] = ['bool', None] self._optionmap['mail_on_success'] = ['bool', 1] + self._optionmap['tweet_on_success'] = ['bool', 1] self._optionmap['archive_style'] = ['str', None] # Release file stuff self._optionmap['generate_release'] = ['bool', 0] @@ -829,7 +846,25 @@ class ArchiveDir: if missing_fields: mail_body = mail_body + "\n\nMissing changefile fields: %s" % missing_fields minidinstall.mail.send(mail_server, 'Mini-Dinstall <%s@%s>' % (getpass.getuser(),socket.getfqdn()), mail_to, mail_body, mail_subject) - + + if self._tweet_on_success: + done = False + missing_fields = [] + if changefile.has_key('changes'): + changefile ['changes_without_dot'] = misc.format_changes(changefile['changes']) + while not done: + try: + tweet_body = tweet_template % changefile + except KeyError, exc: + key = exc.args[0] + changefile[key] = '' + missing_fields.append(key) + else: + done = True + if missing_fields: + tweet_body = tweet_body + "\n\n(errs: %s)" % missing_fields + minidinstall.tweet.send(tweet_body, tweet_server, tweet_user, tweet_password) + if self._post_install_script: try: self._logger.debug("Running post-installation script: " + self._post_install_script) diff --git a/minidinstall/tweet.py b/minidinstall/tweet.py new file mode 100644 index 0000000..548918b --- /dev/null +++ b/minidinstall/tweet.py @@ -0,0 +1,58 @@ +# mail -*- mode: python; coding: utf-8 -*- + +"""Simple tweet support for mini-dinstall.""" + +# Copyright © 2010 Christopher R. Gabriel + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +import logging +import urllib2 +import base64 + +def send(tweet_body, tweet_server, tweet_user, tweet_password): + """Send tweet; on error, log and continue.""" + logger = logging.getLogger("mini-dinstall") + post_url = None + auth_realm = None + if tweet_server == 'identica': + post_url = 'http://identi.ca/api/statuses/update.json' + auth_realm = 'Identi.ca API' + if tweet_server == 'twitter': + post_url = 'http://api.twitter.com/1/statuses/update.json' + auth_realm = 'Twitter API' + + if not post_url: + logger.exception("Unknown tweet site") + if not tweet_user or not tweet_password: + logger.exception("Missing username or password for twitting") + + auth_handler = urllib2.HTTPBasicAuthHandler() + auth_handler.add_password(realm=auth_realm, + uri=post_url, + user=tweet_user, + passwd=tweet_password) + m_http_opener = urllib2.build_opener(auth_handler) + + req = urllib2.Request(post_url) + req.add_data("status=%s" % tweet_body) + handle = None + try: + handle = m_http_opener.open(req) + a = handle.read() + logger.info("Tweet sent to %s (%s)" % (tweet_server, tweet_user)) + except Exception, e: + logger.exception("Error sending tweet to %s ('%s') via %s: %s: %s", tweet_server, tweet_body, tweet_user, type(e), e.args) -- cgit v1.2.3