Using Bazaar VCS with Eclipse
You can use bazaar vcs with Eclipse IDE which I think that is the most complete IDE for python, excluding -because I haven't tried them- wing (proprietary) and Eric (UI is seriously bloated).
Remember to download the latest bzr version from http://bazaar-vcs.org/Download , or you can add the ubuntu feisty repository to your sources.list
sudo echo "deb http://bazaar-vcs.org/releases/debs/feisty ./" >> /etc/apt/sources.list
sudo apt-get update
sudo apt-get dist-upgrade
Warning: If you don't upgrade bzr, the xmloutput won't load!
You also need bazaar-xmloutput plugin, which you should place in ~/.bazaar/plugins/xml
cd ~/.bazaar/plugins
bzr checkout http://bazaar.launchpad.net/~guillo.gonzo/bzr-xmloutput/trunk
mv trunk xml
And finally install the eclipse bzr plugin using the fine howto from http://bazaar-vcs.org/BzrEclipse
I copy / paste from the above website
Installation
1. install the bzr-xmloutput plugin (if you have no idea what I'm talking about please visit the UsingPlugins page for detailed instructions)
2. Launch eclipse
3. Go to Help --> Software updates --> Find and install (see: HelpFindAndInstall).
4. Select Search for new features to install and then --> Next (see: FeatureUpdate).
5. Click New remote site.
6. In the name field, enter Bazaar plugin for Eclipse and in the URL field http://steppenwolf.selfip.net/BazaarEclipse/update (see: UpdateSitesToVisit).
7. Verify that the checkbox for the new update site is checked, and click Finish
8. A dialog with the results should pop-up. (see: UpdateSiteSearchResults)
9. Select the latest version inside bzr-eclipse (actual)
10. Click Finish, and this will launch a wizard (license agreement, etc).
11. Restart Eclipse. Make sure to restart it with "-clean" switch
12. Go to: Window --> Preferences --> Team --> Bazaar. Enter the path to the bzr executable.
* To activate decorators go to: Preferences --> General --> Appearence --> Label Decorations and check Bazaar.
For the time being the plugin seems to function satisfyingly but it's not fully featured and you get the taste that something is not that 'ok', or maybe it's just me
Φτηνά (χρησιμοποιημένα) βιβλία: The arrival
Το practical python που είχα παραγγείλει πριν από 27 μέρες τελικά έφτασε! Πήρε μια εβδομάδα παραπάνω από ότι είχα υπολογίσει στο πρώτο post, αλλά δεν είχα υπολογίσει τον χρόνο που χρειάζεται το βιβλίο να πάει από τον πραγματικό πωλητή στην alibris. Όπως και να έχει, το βιβλίο είναι όντως καινούριο, ατσαλάκωτο και άγραφο και μου κόστισε μόλις 18,5 ευρώ με τα μεταφορικά.
Το καλύτερο νέο όμως ότι η alibris άνοιξε και κατάστημα στην αγγλία, με μεταφορικά μόλις 5,8 ευρώ (+2,5 για κάθε άλλο βιβλίο) και χρόνο παραλαβής 3-14 (!) μέρες.
+1 από μένα για την alibris
Jabber Client Library
Ένα μικρό jabber client module που έγραψα, βασισμένο στο twisted python framework. To client παρέχει όλες τις βασικές συναρτήσεις για login στο jabber server, για επικοινωνία με άλλα jabber accounts και εγκρίνει αυτόματα τις αιτήσεις για "αναγνώριση" (presence notifications)
Στο συγκεκριμένο client έχουν βασιστεί και τα echo, fortune και marx bots (σχετικό post).
#!/usr/bin/env python
from twisted.words.protocols.jabber import jid,xmlstream,client
from twisted.words.xish import domish
from twisted.internet import reactor
from string import join, letters
from random import sample
class Jclient:
def __init__(self, server, username, password, resource="Jclient", port=5222, observers=None):
self.username = username
self.password = password
self.resource = resource
self.server = server
self.port = port
self.observers = observers
def connect(self):
self.myJid = jid.JID('%s/%s' % (self.username, self.resource))
factory = client.basicClientFactory(self.myJid, self.password)
factory.addBootstrap('//event/stream/authd', self.authd)
reactor.connectTCP(self.server, self.port, factory)
reactor.run()
def authd(self, xmlstream):
#save xmlstream
self.xmlstream = xmlstream
# send presence
presence = domish.Element(('jabber:client', 'presence'))
xmlstream.send(presence)
self.watchdog()
def watchdog(self):
if not self.observers:
self.observers = {}
#self.observers['/*'] = self.logger
self.observers['/message'] = self.messageHandler
self.observers['/presence'] = self.presenceHandler
for trigger, function in self.observers.items():
self.xmlstream.addObserver(trigger, function)
def logger(self, xmlstream):
print xmlstream.toXml()
def messageHandler(self, xmlstream):
"""
Returns sender's jid, receiver's jid and message
"""
sender = xmlstream['from']
receiver = xmlstream['to']
message = xmlstream.body.children[0]
id = xmlstream['id']
return sender, receiver, id, message
def send(self, msg):
self.xmlstream.send(msg)
def newMsg(self, to, message, id=None, type="chat"):
if not id:
# generate id
id = 'jc' + join(sample(letters, 5), '')
msg = domish.Element(('jabber:client', 'message'), attribs={'to':to, 'from':self.myJid.full(), 'type': type, 'id': id})
msg.addElement('body', content=message)
return msg
def replyMsg(self, xmlstream, message, type=None):
"""
Creates reply AND sends it
"""
msg = self.newMsg(xmlstream['from'], message, None, type or xmlstream['type'])
self.send(msg)
def presenceHandler(self, xmlstream):
"""
Should implement auto add and auto delete from
presence lists
"""
if 'type' in xmlstream.attributes:
if xmlstream['type'] == 'error':
pass
elif xmlstream['type'] == 'probe':
msg = domish.Element(('jabber:client', 'presence'), attribs = {'to': xmlstream['from'], 'from':xmlstream['to']})
# always free to chat
msg.addElement('show', content="chat")
else:
msg = domish.Element(('jabber:client', 'presence'), attribs = {'type':xmlstream['type'], 'to':xmlstream['from'], 'from':xmlstream['to']})
if msg:
self.xmlstream.send(msg)
def __del__(self):
reactor.stop()
Φτιάχνοντας ένα echo bot σε 22 γραμμές με χρήση του Jclient
#!/usr/bin/env python
from jclient import Jclient
from twisted.words.xish import domish
from twisted.internet import reactor
class Jecho(Jclient):
def __init__(self, server, username, password, resource="Jecho", port=5222):
Jclient.__init__(self,server, username, password, resource, port)
self.connect()
def messageHandler(self, xmlstream):
"""
echoes the same message to sender
"""
(sender, receiver, id, message) = Jclient.messageHandler(self,xmlstream)
self.replyMsg(xmlstream,message)
jecho = Jecho("localhost", "server@localhost", "1")
Jabber bots

Έπαιξα τις τελευταίες δύο εβδομάδες με το xmpp το πρωτόκολλο πίσω από το δίκτυο jabber το μεγαλύτερο free as in speech instant messaging δίκτυο. Το jabber πήρε τα πάνω του από τότε που το gmail αποφάσισε να υποστήριξει instant messaging τεχνολογίες με το jabber μέσα από το webmail client .
Το ίδιο το jabber είναι αποκεντρωποιημένο δίκτυο -στην λογική που λειτουργεί και το email- οπότε ο καθένας μπορεί να στήσει έναν jabber server και όλοι οι servers επικοινωνούν μεταξύ τους για να ανταλλάξουν τα μηνύματά τους οι χρήστες.
Επίσης αξίζει να σημειωθεί ότι το xmpp είναι ουσιαστικά ανταλλαγή xml μηνυμάτων κάτι που το κάνει φοβερά extensible. Μπορείς για παράδειγμα να το χρησιμοποιήσεις για application2application messaging για να δημιουργήσεις ένα message queue σε κατανεμημένα συστήματα κτλ.
Στο ψητό τώρα, χρησιμοποιήσα την twisted python, έναν ενδιαφέρον programming framework για network (και όχι μόνο) programming σε python.
Έγραψά ένα jabber client class βασισμένο στο twisted python jabber protocol και βάση αυτού έφτιαξα τρία services.
- To echo service (echo@jabber.sealabs.net): που κάνει απλά echo ότι του λες
- Το fortune service (fortune@jabber.sealabs.net): που σου στέλνει ένα fortune cookie (από το πρόγραμμα fortune του linux) κάθε φορά που γίνεσαι available
- και... το καλύτερο τον Karl Marx (marx@jabber.sealabs.net) ένα chatbot βασισμένο στο megahal και εκπαιδευμένο με το Κομμουνιστικό Μανιφέστο
Μπορείτε να κάνετε add buddy τα παραπάνω και θα κάνουν άμεσα authorise. Οι συζητήσεις σας με τα παραπάνω bot και κυρίως με τον Marx μπορεί να καταγράφονται για όλους ψυχαγωγίας
Θα ανεβάσω και τους σχετικούς κώδικές γιατί αυτό το ριμάδι το twisted python δεν έχει ολοκληρωμένο documentation
Playlist για το e-radio.gr
Έφτιαξα ένα playlist με όλους τους σταθμούς από το e-radio.gr γιατί ο firefox (βλέπε bloatfox) έχει αρχίσει να είναι πολύ ασταθής τώρα τελευταία και προτιμώ να ακούω τους σταθμούς μου χωρίς crash
Για τους ενδιαφερόμενους ορίστε και το script που με βοήθησε να το κάνω (αν και δεν είναι και τίποτα φοβερό!):
#!/usr/bin/env python
import re, urllib
HTML = urllib.urlopen("http://www.e-radio.gr").readlines()
#print HTML
sstring = re.compile("(?<=Repository\/Radios\/gr\/)[A-Za-z]+|(?<=\)[A-z0-9., ]+")
k = 1
for line in HTML:
radios = sstring.findall(line)
i = 0
while i+1 < len(radios):
print "File%d=mmsh://live.onestreaming.com/%s?MSWMExt=.asx" % (k,radios[i])
print "Title%d=%s" %(k,radios[i+1])
i += 2
k += 1
Uno playing cards with Scribus and Python
![]()
Everybody likes UNO. You can play it uuno-cardssing common playing cards or can buy an UNO pack from your local toy store but I prefer using my homemade GPLed cards!
Here is a small howto to make yours or download the PDF to print yours right away!
Stuff you will need
- Project DUO implements a free UNO game using python. They are so kind to offer us free GPLed uno card images.
- Scribus is a open source desktop publishing program with scripting capabilities using python
- Python programming language
I ripped off IDgen-NG, removed a lot of code, made some improvents and modifications to fit my needs. The resulting scribus script asks for a directory containing your uno cards images and then creates a document placing those images the one next to the other. The output is a dozen pages of physical sized, ready to print and cut uno playing cards, with almost no effort!
Of course this script can be used to produce any kind of playing cards!
Usage:
Open Scribus -> Script -> Execute Script -> Select uno.py (download uno.py)
Select dir containing card images. That's it!
Now print, cut, and enjoy your game!
IP over DNS How To
To howto αυτό θα μας δείξει πως να δρομολογήσουμε δεδομένα IP (TCP, UDP κτλ) "πάνω" ή καλύτερα μέσα σε DNS δεδομένα τύπου ΤΧΤ. Με απλά ελληνικά: πως θα πάρω πρόσβαση στο internet από εκείνο το wifi hotspot στο πλοίο (ή το αεροδρόμιο ή οπουδήποτε έχουν το θράσος να χρεώνουν γι' αυτό το απαραίτητο αγαθό της ζωής!)
Συστατικά:
- Ένα linux laptop σε τοποθεσία με επί-πληρωμή wifi. Κατα προτίμηση με κάτι debian based. Εγώ το έκανα με Ubuntu
- Ένας linux server
- Ένα domain που να μπορούμε να επεξεργαστούμε τα subdomain του
- Το nstx λογισμικό (debian πακέτο nstx) website
Βασική ιδέα
Η βασική ιδέα πίσω από το όλο εγχείρημα είναι η εξής. Βρισκόμαστε σε ένα χώρο με wifi hotspot στο οποίο μπορούμε να συνδεθούμε, παίρνουμε IP και μόλις ζητήσουμε ένα site αντί για το site εμφανίζεται μία ωραία σελίδα που σου λέει να βάλεις τον κωδικό σου. Σε αυτές τις περιπτώσεις συνήθως επιτρέπεται να κάνεις ping ή/και dns queries χωρίς πρόβλημα. Οπότε αμέσως το διαβολάκι πάνω από τον αριστερό σου ώμο σε ρωτάει: "Δεν είναι δυνατόν να δρομολογήσουμε κάπως δεδομένα IP "πάνω" από ICMP (ping) ή DNS?" Φυσικά και είναι δυνατόν.
Σε δύο εγκαταστάσεις με αυτό το σύστημα που έχω δει, επιτρέπουν και οι δύο ping και dns δεδομένα χωρίς να τα φιλτράρουν (τα dns φυσικά μόνο προς τον δικό τους dns server). Δυστυχώς όμως οι λύσεις IP over ICMP (παρόλο που υπάρχουν πολλές στο google και το ptunnel σε πακέτο στο ubuntu) δεν έπαιξαν επειδή έπαιρνες εσωτερικό IP και είχες πρόσβαση στο δίκτυο μέσω NAT. Οπότε κάπου κόλλαγε η διαδικασία.
Απορρίπτουμε λοιπόν το IP over ICMP και πάμε στο πιο δύσκολο στο set-αρισμα, αλλά πολύ πιο πιθανό να παίζει εάν όχι σε όλες, τουλάχιστον στις περισσότερες εγκαταστάσεις τέτοιου τύπου IP over DNS. Με απλά λόγια αυτό που κάνουμε είναι ο εξής, δημιουργούμε ένα κανάλι δεδομένων στο οποίο αποστέλλουμε πληροφορία κωδικοποιημένη στο subdomain για το οποίο ζητάμε πληροφορίες και λαμβάνουμε πληροφορία κωδικοποιημένη στο TXT πεδίο της DNS απάντησης. Δηλαδή όταν ζητάμε να μάθουμε για το domain jsKsje38.tunnel.foo.gr στην ουσία λέμε στην άλλη μεριά του καναλιού ssh root@1.2.3.4 και η απάντηση μας έρχεται ο DNS πληροφορία κ.ο.κ.
Για να παίξει αυτό θα πρέπει να κάνουμε ρυθμίσεις στο dns server που διαχειρίζεται το domain μας foo.gr, να έχουμε ένα άλλο μηχάνημα που να μην τρέχει DNS για να τρέξουμε τον nstx server που πρέπει να καταλαβαίνει τι του στέλνουμε και να μας απαντά κατάλληλα (έστω ότι έχει την IP 1.2.3.4) και φυσικά να ρυθμίσουμε το nstx client στο laptop.
DNS site:
Έστω ότι έχουμε το domain foo.gr, θα πρέπει να δημιουργήσουμε δύο νέες καταχωρήσεις στο dns server μας τύπου
tunnel.foo.gr. 1 IN NS ntunnel.foo.gr.
ntunnel.foo.gr. 1 IN A 1.2.3.4
Όπου tunnel.foo.gr είναι το domain που θα χρησιμοποιήσουμε ως tunnel για να μεταφέρουμε τα ΤΧΤ δεδομένα μας και πληροφορίες για το domain αυτό θα μας δίνει ο ntunnel.foo.gr nameserver που ακούει στην διεύθυνση 1.2.3.4.
TIP: Για να λειτουργήσει το σύστημα δεν θέλουμε αναγκαστικά δύο μηχανήματα. Μπορούμε να δώσουμε σε μία κάρτα δικτύου δύο διαφορετικά (ή και παραπάνω IP) χρησιμοποιώντας IP aliasing. Φυσικά πρέπει να έχουμε δύο διαφορετικά public IP. Στο παράδειγμά μας έχουμε τα IP 1.2.3.3 (o dns server μας) και το 1.2.3.4 (o nstx server μας).
Server side:
Χρησιμοποιούμε το ip aliasing για να δημιουργήσουμε το interface eth0:1 με την διεύθυνση 1.2.3.4
ifconfig eth0:1 1.2.3.4 netmask 255.255.255.0 up
Κατεβάζουμε το nstx
apt-get install nstx
To nstx χρησιμοποιεί το αρχείο /etc/default/nstx για την ρύθμισή του, αλλά κάτι πήγαινε στραβά με αυτό και το έτρεξα με το χέρι.
Τρέχουμε το nstx server
nstxd -i 1.2.3.4 tunnel.foo.gr
Όπου -i σημαίνει να ακούει μόνο στην διεύθυνση 1.2.3.4 (στην διεύθυνση 1.2.3.3 έχουμε τον πραγματικό DNS) και να επεξεργάζεται δεδομένα του domain tunnel.foo.gr.
Επίσης δημιουργούμε το interface που θα χρησιμοποιήσει το nstx server για να μεταφέρει δεδομένα
modprobe tun
ifconfig tun0 10.0.0.1 netmask 255.0.0.0 up
Τέλος θέλουμε ότι δεδομένα φτάνουν στο tun0 interface (δηλαδή δεδομένα από τον nstx server) να μπορούν να έχουν πρόσβαση στο net, οπότε θα χρησιμοποιήσουμε IP Masquarate για να τα δρομολογήσουμε μέσω του interface eth0 που έχει πρόσβαση στο διαδίκτυο.
Εγκαθιστούμε το iptables και κάνουμε τις κατάλληλες ρυθμίσεις
apt-get install iptables
iptables -t nat -A POSTROUTING -s 10.0.0.0/8 -o eth0 -j MASQUERADE
iptables -I FORWARD -j ACCEPT -s 10.0.0.0/8
echo "1" >> /proc/sys/net/ipv4/ip_forward
Συνοψίζουμε: Όποιος ζητήσει πληροφορίες για το domain tunnel.foo.gr θα μάθει ότι ο nameserver του tunnel.foo.gr είναι το ntunnel.foo.gr που ακούει στην διεύθυνση 1.2.3.4. Άρα θα στείλει τον DNS server στην διεύθυνση 1.2.3.4 δηλαδή τον nstx server δεδομένα, τα οποία το nstx τα μεταφράζει σε χρήσιμα δεδομένα και τα δρομολογεί στο interface eth0.
Client side:
Έχουμε συνδεθεί στο δίκτυο και έχουμε IP. Πρέπει να μάθουμε μερικά πράγματα για το δίκτυο που βρισκόμαστε. Πρώτα το IP του dns server που πρέπει να χρησιμοποιούμε. Βρίσκεται στο αρχείο /etc/resolv.conf . Δεύτερον το IP του gateway που έχουμε τώρα.
H καταχώρηση στο route table με flags UG είναι το gateway μας
route -n
Destination Gateway Genmask Flags Metric Ref Use Iface
xx.xx.xx.xx 0.0.0.0 255.255.255.248 UG 0 0 0 eth0
Κατεβάζουμε το nstx (το έχουμε από πριν! θυμάστε ότι δεν έχουμε πρόσβαση εδώ που βρισκόμαστε!)
apt-get install nstx
Και το εκτελούμε
nstxcd tunnel.foo.gr <ip dns server που πρέπει να χρησιμοποιούμε>
Δημιουργούμε το interface για το nstxcd
modprobe tun
ifconfig tun0 up 10.0.0.2 netmask 255.255.255.0
Και τώρα πρέπει να ορίσουμε ως νέο default interface το tun0 και να δρομολογούμε από το παλιό μόνο τις αιτήσεις DNS.
route del defautl
route add default gw 10.0.0.1 tun0
route add -host gw dev eth1
To eth1 είναι το wifi device στο laptop. Σε άλλους μπορεί να είναι wlan.
Voila! Τώρα όλα τα δεδομένα δρομολογούνται μέσω του tun0 μεταφράζονται σε dns queries κ.ο.κ. και εσύ απολαμβάνεις internet access χωρίς να πληρώνεις 10 ευρώ τα 15' λεπτά! (ναι για τέτοιες τιμές μιλάμε!)
Τελικές παρατηρήσεις:
Δεν ξέρω για άλλους χώρους, αλλά στα πλοία η πρόσβαση στο Inet πέρα από πανάκριβη είναι και τόσο ασταθής και αργή που ουσιαστικά δεν μπορεί να χρησιμοποιηθεί. Προσωπικά κατάφερα μερικά ssh connections (για web ούτε για αστείο) χρησιμοποιώντας συμπίεση και ssh version 1 (δεν ξέρω γιατί αλλά έπαιζε καλύτερα από το δύο. μάλλον λιγότερα δεδομένα
και αυτές δεν διαρκούσαν παραπάνω από 1-2 εντολές, εάν έφταναν μέχρι εκεί.