External Content not shown. Further Information.
Science, Software, Hardware:
Zeroth World:
Comics/Images/Audios/Videos:
Quotes:
External Content not shown. Further Information.
Popular Culture:
Nerd Culture:
Science, Software, Hardware:
Zeroth World:
Comics/Images/Audios/Videos:
Quotes:
External Content not shown. Further Information.
Popular Culture:
Nerd Culture:
Science, Software, Hardware:
Comics/Images/Audios/Videos:
External Content not shown. Further Information.
The general state of instant messaging is horrible. Google - once the most preferrable commercial XMPP provider - dropped federation, and some people say that they even plan to shut down the XMPP access at all. Facebook already announced that it will do so, but at least provides an open API as alternative, for which there is already an experimental BitlBee extension. Skype dropped its public API a while ago. So while the Linux folks keep building their new ivory tower, all the achievements of the last decades seem to slowly vanish.
Anyway, so there we are, at a time when one must be glad if the "non-computer-people" regularily use Facebook instead of Skype chats. But some do, and since I hate the original Skype client, I spent a few hours in search for alternatives to the public API. Even though I did not yet write anything really usable, I'd like to share what I found out, to give other people inspiration, and as notes for myself. Everything mentioned here is experimental. Furthermore, I am in no way affiliated with Skype or Microsoft.
In theory, it should be possible to access Skype chats via MSN. This page has a nice summary about MSN servers that work. However, though I can manage to log in, my Skype contacts are not shown, and I do not get Skype messages. Not sure what I am doing wrong.
Skype chats can now be accessed via Outlook's Webinterface. It would have been nice to use this webinterface with edbrowse, but it does not even load. It is probably possible to reverse engineer this interface. But then again, web interfaces can be changed, and obfuscated. However, this webinterface seems to use MSNP24, and people are trying to reverse engineer it. This is probably the most promising approach. On the other hand, it is probably violating some terms of use.
My approach was different: I was trying to use the official client, as one would have done with the old public API. I was trying to use AT-SPI, specifically pyatspi2, since orca appears to work well with Skype. I used the accerciser tool to examine Skype.
Skype uses 32 bit Qt, so be sure to have qt-at-spi for that
architecture. Under x64 Ubuntu, the package is called
qt-at-spi:i386. Make sure that QT_ACCESSIBILITY=1 for your
session. If accerciser shows you an entry for Skype, you know that you
did it correctly.
The following script works fairly reliable for me and shows the contacts in my contact list. I am using the client version 4.3.0.37. Furthermore, this only works with the English language setting, and the window should not be iconified.
# -*- coding: utf-8 -*-
import pyatspi
import time
reg = pyatspi.Registry
skype = None
def getElementBy(parent, prop):
for i in range(0, parent.getChildCount()):
if prop(parent[i]):
return parent[i]
else:
child = getElementBy(parent[i], prop)
if child != None:
return child
return None
for i in range(0, reg.getDesktopCount()):
d = reg.getDesktop(i)
for app in d:
if app.name == "skype":
skype = app
if skype is None:
print("skype is None")
exit (-1)
# the main window is unique (hopefully)
mainwindowmenu = getElementBy (skype, lambda x: x.get_role_name() == 'menu bar')
if mainwindowmenu is None:
print("mainwindowmenu is None")
exit(-1)
contacts = getElementBy(mainwindowmenu.get_parent(),
lambda x: x.name =='Contacts')
if contacts is None:
print("contacts is None")
exit(-1)
for i in range(0, contacts.getChildCount(), 7):
if i != 0:
p = contacts[i].get_position(0)
print(contacts[i].name + " → (" + str(p.x) + ", " + str(p.y) + ")")
The less reliable part now is actually sending messages. If the contact list is in the foreground, and sufficiently large to show all contacts, then you can send double clicks on the contact you want to chat with, to open the chat window
p = contacts[14].get_position(0)
reg.generateMouseEvent(p.x+2, p.y+2, pyatspi.MOUSE_B3D)
As I said, this is not really reliable, it is very fragile. Maybe on an own dedicated X-Server with a huge virtual screen, this could be used. To actually set the message that is to be sent, I had to hack a bit: Skype sometimes keeps other message text boxes in the background. However, their size is always zero. The following is very bad style, as it creates a busy infinite loop if something goes wrong. But as a proof-of-concept, it is ok, I guess.
msg = None
while msg is None:
msg = getElementBy(skype,
lambda x: (x.name == 'Send a message') and
(x.get_size().x != 0))
time.sleep(.2)
msg.set_text_contents("This is a test")
So far so good. Sometimes Skype crashes when doing this. But mostly it works. It brings the text window to front. To actually send the message, we can send the Return key:
reg.generateKeyboardEvent(36, None, pyatspi.KEY_PRESSRELEASE)
Another way of sending keystrokes and even resizing and moving windows
is xdotool(1), which could come handy when using this method to send
messages.
To receive messages, it is probably the easiest to just poll the
sqlite database main.db in ~/.Skype/, which is in a subdirectory
named after the account name. It has a table "Messages". To get the
timestamp of the last message (which you probably want when starting
your script)
select MAX(timestamp) from Messages;
then, assuming it was 1421498680, messages can be queried using
select id, author, body_xml from Messages where timestamp >= 1421498680;
In summary, try to convince your friends to use Facebook if they really want a commercial chat provider. Run a good XMPP server (with auto-ping and low tcp keepalive timeout and XEP-0313 or even XEP-0136 I'll probably do so when jessie gets stable), and offer them accounts. And if you really have to use Skype, face the evil!
Update: This project seems nice.
External Content not shown. Further Information.
Popular Culture:
Nerd Culture:
Science, Software, Hardware:
Zeroth World:
Comics/Images/Audios/Videos:
Quotes:
I have written before about dnsmasq and pxe-booting. I was setting up an old thin client as a print server, which could not boot from usb sticks. Therefore, I needed to run a pxe-server to install debian on its internal memory.
So here is a short description. This is more a "note-to-self", and especially, this kind of stuff keeps changing the way it works from now and then. But at least, sharing it with the world might make it easier for you to find a solution.
This setup is not for permanently running servers. It is for connecting a single other computer to a laptop via ethernet, booting it, and installing.
I want my computer to route from the interface eth0 to
wlan0. wlan0 is managed by network-manager. For eth0, my
interfaces(5) contains
iface eth0 inet static
address 192.168.222.1
netmask 255.255.255.0
Make sure to restart your entire network setup, including
network-manager, otherwise, network-manager might try to keep setting
up eth0. (I am not sure whether one can do this with network-manager
too.)
Furthermore, the sysctl(8)-setting net.ipv4.ip_forward must be set
to 1. I put that setting into my sysctl.conf(5) and reloaded, but
it can be set directly, so it is not persistent. To make eth0 a NAT
to wlan0, I run
sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
My working directory is /home/christoph/software/pxesetup. In this,
I have a file dnsmasq.conf with the contents
interface=eth0
bind-interfaces
dhcp-range=eth0,192.168.222.1,192.168.222.128,12h
dhcp-authoritative
enable-tftp
tftp-root=/home/christoph/software/pxesetup/tftp/
dhcp-boot=pxelinux.0
listen-address=192.168.222.1
Be careful to change the interface name accordingly: You will be
running an authoritative dhcp server, do not do this in networks you
do not own. Now we need the pxelinux files from Debian, which can (at
the time of writing this) be found
here
and
here. Create
/home/christoph/software/pxesetup/tftp, and put pxelinux.0 in that
directory, and uncompress the tarball into it (it creates a
subdirectory debian-installer). Do a chmod -R a+rwx on that
directory - server-installations should set the permissions more
carefully, but for one-time-installations with my own laptop, it is
sufficient.
Finally, run
sudo dnsmasq -dC /home/christoph/software/pxesetup/dnsmasq.conf
connect your client and let it boot via PXE. I hope this helps. At least it will help me to remember my setup. Comments and corrections are welcome, just send me an e-mail.