Skip to main content

Ralsina.Me — Roberto Alsina's website

Posts about programming (old posts, page 31)

Linux as a windows crutch: Sending SMS

Sup­pose you want to send SMS mes­sages from win­dows through a blue­tooth con­nec­tion to a phone.

I am sure you can make it work. On the oth­er hand, I al­ready had it work­ing on Lin­ux... so you can just use this on a friend­ly Lin­ux box, and send SMS mes­sages by ac­cess­ing a spe­cial URL:

#!/usr/bin/env python
from colubrid import BaseApplication, HttpResponse, execute
import os

class SMSApplication(BaseApplication):

  def process_request(self):
      numero = self.request.args.get('numero')
      mensaje = self.request.args.get('mensaje')
      [entrada,salida]=os.popen4('/usr/bin/gnokii --sendsms %s'%numero,mode='rw')
      entrada.write(mensaje)
      entrada.flush()
      entrada.close()
      msg=salida.read()
      response = HttpResponse(msg)
      response['Content-Type'] = 'text/plain'
      return response

if __name__ == '__main__':
  execute(SMSApplication,debug=True, hostname='mybox.domain.internal', port=8080,reload=True)

If someone opens http://my­box.­do­main.in­ter­nal:8080/?nu­mero=1234?­men­saje=ho­la%20­mun­do it sends "hola mundo" to the 1234 number.

I sup­pose I could call this a web tele­pho­ny ser­vice or some­such, but it's ac­tu­al­ly just the 5'­so­lu­tion that came to mind.

It us­es a sil­ly lit­tle not-a-we­b-frame­work called col­u­brid in­stead of some­thing you may know, be­cause I want­ed to keep it sim­ple, and it does­n't get much sim­pler than this.

A simple memcache memoizer for python>=2.2

Just a snip­pet of code be­cause ev­ery once in a while I need some­thing like the clas­sic mem­o­ize dec­o­ra­tor but am work­ing on a Cen­tOS 4 bix (with python 2.3!)

I am still test­ing it, and am not even sure it re­al­ly work­s, but it should be close.

cache=memcache.Client(['127.0.0.1:11211'], debug=0)
cachetimeout=30

def memoize(fun):
    def inner(*args, **kwargs):
        key=repr(fun)+repr(args)+repr(kwargs)
        cached = cache.get(key)
        if cached is None:
            val = fun(*args, **kwargs)
            print "Setting: ",key, "to: ",val
            cache.set(key,val,cachetimeout)
            return val
        return cached
    return inner

And lat­er in­side a class:

def myfun(self,arg):
   :
   :
myfun=memoize(myfun)

And that's it. The ba­sic idea I stole from a blog who was in­spired by a Paul Gra­ham book. It can be triv­ial­ly turned in­to a dec­o­ra­tor, of course (but then on­ly works on 2.4 and lat­er).

Playing with GIT

The guys at http://github.­com have been nice enough to add me to their be­ta pro­gram, so I am do­ing a lit­tle project there, to fig­ure out if I like git or not.

Since ev­ery­one raves about it, I sup­pose I will, and then will have to turn my nu­mer­ous google­code SVN re­pos in­to git mir­rors or what­ev­er the cor­rect ter­mi­nol­o­gy is.

New qmail plugin idea: overload

It should not hap­pen but it does: Your qmail serv­er is over­load­ed. Maybe you are un­der a DOS at­tack, or there is a rea­son why you are get­ting 10x your usu­al amount of mail.

But then you start see­ing how your "not pre­pro­cessed" queue starts grow­ing, and grow­ing...

This can al­so mean things like cla­mav or spa­mas­sas­s­in, which need to check the mail be­fore it gets queued are not keep­ing up with the mail flow, or maybe some IO per­for­ma­ce is­sue.

But what can you do righ now to fix it?

Well, you can dis­able spa­mas­sas­s­in, or, in ex­treme cas­es, shut­down SMTP so the sys­tem has a chance to catch its breath so to speak.

Of course, clos­ing SMTP means your own users can't send email ei­ther, which suck­s.

Now there is a lighter al­ter­na­tive: shut­down SMTP for those who are not your user­s.

Here's the triv­ial code, im­ple­ment­ed as a SPP plug­in, fit to be used in the [mail] sec­tion:

#!/bin/dash

if [ -f /var/qmail/control/overloaded ]
then
      if [ -z "$SMTPAUTHUSER" ]
      then
              echo R451 Temporary Failure: Server overload
              echo overload: $PPID Temporary Failure: Server overload >&2
      fi
fi

And if you are dar­ing and want to make your sys­tem self­-­cor­rect­ing, maybe you should cron some­thing like this:

* * * * * if [ `qmail-qstat  | tail -1 | cut -d: -f2` -gt 100 ];\
then touch /var/qmail/control/overloaded ;\
else rm -f /var/qmail/control/overloaded; fi

I will prob­a­bly code it again in C and make it part of ra/­plu­g­in­s.

Weird Django/PyODB bug

I am fin­ish­ing my first large-ish Djan­go app from scratch [1].

To lo­gin a us­er you can do some­thing like this:

[root@wally app]# python manage.py shell
Python 2.3.4 (#1, May  2 2007, 19:26:00)
[GCC 3.4.6 20060404 (Red Hat 3.4.6-8)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from pyodb import *
>>> import django.contrib.auth
>>> print django.contrib.auth.authenticate(username='user',password='pass')
user

And then you use that us­er ob­ject for djan­go.­con­trib.auth.lo­gin

Some of the au­then­ti­ca­tion da­ta is avail­able on a Mi­cro­soft SQL Server, and I get it via py­o­d­b. And this hap­pens when I try to au­then­ti­cate the us­er (as­sume us­er and pass are valid, this is the small­est snip­pet that trig­gers the bug):

[root@wally app]# python manage.py shell
Python 2.3.4 (#1, May  2 2007, 19:26:00)
[GCC 3.4.6 20060404 (Red Hat 3.4.6-8)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from pyodb import Connect
>>> import django.contrib.auth
>>> c1=Connect("sqlserver",uid="user",pwd="pass")
>>> print django.contrib.auth.authenticate(username='user',password='pass')
None

As you can see, the py­o­db stuff should not in­ter­fere with the djan­go stuff at al­l. I am on­ly im­port­ing one func­tion and con­nect­ing to the DB, I don't even ex­e­cute any SQL or use any da­ta from the SQL con­nec­tion. But the calls to au­then­ti­cate fail.

How are you sup­posed to de­bug this? I worked around it by mov­ing the Py­O­DB stuff to an­oth­er mod­ule, but it's weird.


Contents © 2000-2023 Roberto Alsina