Compare commits

..

No commits in common. "master" and "v0.1.6" have entirely different histories.

7 changed files with 96 additions and 176 deletions

View File

@ -48,7 +48,7 @@ Install via pip:
Clone the repository: Clone the repository:
$ git clone https://git.daemons.it/drymer/jabbergram $ git clone git://daemons.cf/jabbergram
$ cd jabbergram $ cd jabbergram
$ su -c "pip3 install -r requirements.txt" $ su -c "pip3 install -r requirements.txt"
$ su -c "python3 setup.py install" $ su -c "python3 setup.py install"
@ -128,9 +128,9 @@ Instalar a través de `pip`:
Clonar el repositorio: Clonar el repositorio:
$ git clone https://git.daemons.it/drymer/jabbergram $ git clone git://daemons.cf/jabbergram
$ cd jabbergram $ cd jabbergram
$ su -c "pip3 install -r requirements.txt" $ su -c "pip3 instalar -r requirements.txt"
$ su -c "python3 setup.py install" $ su -c "python3 setup.py install"
### Configuración<a id="orgheadline9"></a> ### Configuración<a id="orgheadline9"></a>
@ -145,7 +145,7 @@ Este programa es simple, no tiene ni un menú de `ayuda`. Lo primero que hay que
NombreDelBot NombreDelBot
# Ahora hay que pulsar desactivar # Ahora hay que pulsar desactivar
La opción `/setprivacy` es para hacer que el robot pueda leer todo lo que se dice en el grupo, no sólo cuando se utilizan los comandos. Es necesario para hacer que `jabbergram` funcione. Más información sobre la creación los bots de `Telegram` en su [página web](https://core.telegram.org/bots). La opción `/setprivacy` es para hacer que el robot pueda leer todo lo que se dice en el grupo, no sólo cuando se utilizan los comandos. Es necesario para hacer que `jabbergram` funcione. Más información sobre la creación los bots de `Telegrama` en su [página web](https://core.telegram.org/bots).
A continuación, hay que crear un archivo de configuración, que llamaremos `config.ini`. En ese archivo, introduce los siguientes parámetros: A continuación, hay que crear un archivo de configuración, que llamaremos `config.ini`. En ese archivo, introduce los siguientes parámetros:
@ -173,7 +173,7 @@ Sólo puede haber un archivo de configuración. Esto es debido a que sólo puede
token = jabbergramBotTokken token = jabbergramBotTokken
group = -10293943920 120301203 group = -10293943920 120301203
De este modo, el muc "exampleMuc@muc.nope.org" se sincronizará con el grupo "-10293943920", y "segunda@muc.sip.org" con "120301203". Hecho esto, solo queda ejecutarlo en la terminal: `python3 jabbergram.py config.ini`. Hay que tenerla activa siempre que se quiera que funcione, obviamente. De este modo, el muc "exampleMuc@muc.nope.org" se sincronizará con el grupo "-10293943920", y "segunda@muc.sip.org" con "120301203".
### Licencia<a id="orgheadline11"></a> ### Licencia<a id="orgheadline11"></a>

View File

@ -14,7 +14,7 @@
Clone the repository: Clone the repository:
#+BEGIN_SRC sh #+BEGIN_SRC sh
$ git clone https://git.daemons.it/drymer/jabbergram $ git clone git://daemons.cf/jabbergram
$ cd jabbergram $ cd jabbergram
$ su -c "pip3 install -r requirements.txt" $ su -c "pip3 install -r requirements.txt"
$ su -c "python3 setup.py install" $ su -c "python3 setup.py install"
@ -93,9 +93,9 @@
Clonar el repositorio: Clonar el repositorio:
#+BEGIN_SRC sh #+BEGIN_SRC sh
$ git clone https://git.daemons.it/drymer/jabbergram $ git clone git://daemons.cf/jabbergram
$ cd jabbergram $ cd jabbergram
$ su -c "pip3 install -r requirements.txt" $ su -c "pip3 instalar -r requirements.txt"
$ su -c "python3 setup.py install" $ su -c "python3 setup.py install"
#+END_SRC #+END_SRC
*** Configuración *** Configuración
@ -111,7 +111,7 @@
# Ahora hay que pulsar desactivar # Ahora hay que pulsar desactivar
#+END_SRC #+END_SRC
La opción =/setprivacy= es para hacer que el robot pueda leer todo lo que se dice en el grupo, no sólo cuando se utilizan los comandos. Es necesario para hacer que =jabbergram= funcione. Más información sobre la creación los bots de =Telegram= en su [[https://core.telegram.org/bots][página web]]. La opción =/setprivacy= es para hacer que el robot pueda leer todo lo que se dice en el grupo, no sólo cuando se utilizan los comandos. Es necesario para hacer que =jabbergram= funcione. Más información sobre la creación los bots de =Telegrama= en su [[https://core.telegram.org/bots][página web]].
A continuación, hay que crear un archivo de configuración, que llamaremos =config.ini=. En ese archivo, introduce los siguientes parámetros: A continuación, hay que crear un archivo de configuración, que llamaremos =config.ini=. En ese archivo, introduce los siguientes parámetros:
@ -141,7 +141,7 @@
group = -10293943920 120301203 group = -10293943920 120301203
#+END_SRC #+END_SRC
De este modo, el muc "exampleMuc@muc.nope.org" se sincronizará con el grupo "-10293943920", y "segunda@muc.sip.org" con "120301203". Hecho esto, solo queda ejecutarlo en la terminal: =python3 jabbergram.py config.ini=. Hay que tenerla activa siempre que se quiera que funcione, obviamente. De este modo, el muc "exampleMuc@muc.nope.org" se sincronizará con el grupo "-10293943920", y "segunda@muc.sip.org" con "120301203".
*** Licencia *** Licencia
#+BEGIN_SRC text #+BEGIN_SRC text
This program is free software: you can redistribute it and / or modify This program is free software: you can redistribute it and / or modify

View File

@ -31,7 +31,7 @@ Clone the repository:
.. code-block:: sh .. code-block:: sh
:number-lines: 0 :number-lines: 0
$ git clone https://git.daemons.it/drymer/jabbergram $ git clone git://daemons.cf/jabbergram
$ cd jabbergram $ cd jabbergram
$ su -c "pip3 install -r requirements.txt" $ su -c "pip3 install -r requirements.txt"
$ su -c "python3 setup.py install" $ su -c "python3 setup.py install"
@ -135,7 +135,7 @@ Clonar el repositorio:
.. code-block:: sh .. code-block:: sh
:number-lines: 0 :number-lines: 0
$ git clone https://git.daemons.it/drymer/jabbergram $ git clone git://daemons.cf/jabbergram
$ cd jabbergram $ cd jabbergram
$ su -c "pip3 instalar -r requirements.txt" $ su -c "pip3 instalar -r requirements.txt"
$ su -c "python3 setup.py install" $ su -c "python3 setup.py install"

View File

@ -1,42 +1,33 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import configparser
import logging
from sys import argv
from threading import Thread
from time import sleep
from xml.dom import minidom
import sleekxmpp
import telegram
from sleekxmpp.xmlstream.stanzabase import ElementBase
from telegram.error import NetworkError, Unauthorized
try: try:
import requests import requests
except: except:
logging.error("HTTP Upload support disabled.") print("HTTP Upload support disabled.")
import sleekxmpp
import telegram
import configparser
from threading import Thread
from queue import Queue
from telegram.error import NetworkError, Unauthorized
from time import sleep
from sys import argv
from sys import exit
from sleekxmpp.xmlstream.stanzabase import ElementBase
from sleekxmpp.stanza.iq import Iq
from xml.dom import minidom
class Request(ElementBase): class Request(ElementBase):
"""Special class to create http_upload requests."""
namespace = 'urn:xmpp:http:upload' namespace = 'urn:xmpp:http:upload'
name = 'request' name = 'request'
plugin_attrib = 'request' plugin_attrib = 'request'
interfaces = set(('filename', 'size')) interfaces = set(('filename', 'size'))
sub_interfaces = interfaces sub_interfaces = interfaces
class Jabbergram(sleekxmpp.ClientXMPP): class Jabbergram(sleekxmpp.ClientXMPP):
"""Main object.""" def __init__(self, jid, password, rooms, nick, token, groups):
def __init__(self, jid, password, rooms, nick, token, groups, verify_ssl):
"""
Executed when the class is initialized. It adds session handlers, muc
handlers and send the telegram reading function and the HTTP upload
initializing functions to their respective threads.
"""
# XMPP # XMPP
super(Jabbergram, self).__init__(jid, password) super(Jabbergram, self).__init__(jid, password)
self.add_event_handler('session_start', self.start) self.add_event_handler('session_start', self.start)
@ -47,7 +38,6 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.token = token self.token = token
self.xmpp_users = {} self.xmpp_users = {}
self.jid = jid self.jid = jid
self.verify_ssl = verify_ssl
for muc in self.muc_rooms: for muc in self.muc_rooms:
self.add_event_handler("muc::%s::got_online" % muc, self.add_event_handler("muc::%s::got_online" % muc,
@ -75,11 +65,6 @@ class Jabbergram(sleekxmpp.ClientXMPP):
'connected') 'connected')
def init_http(self): def init_http(self):
"""
Initializes HTTP upload support. Sends a discovery stanza to the server
to find the HTTP upload component and asks for the max size a file can
be.
"""
self.http_upload = self.HttpUpload(self) self.http_upload = self.HttpUpload(self)
self.component = self.http_upload.discovery() self.component = self.http_upload.discovery()
@ -99,7 +84,6 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.max_size = None self.max_size = None
def read_tg(self): def read_tg(self):
"""Main telegram function."""
update_id = 0 update_id = 0
# wait until http_upload has been tested # wait until http_upload has been tested
@ -108,29 +92,12 @@ class Jabbergram(sleekxmpp.ClientXMPP):
try: try:
for update in self.bot.getUpdates(offset=update_id, for update in self.bot.getUpdates(offset=update_id,
timeout=10): timeout=10):
name = ''
size = 0
if update.edited_message:
update_id = update.update_id + 1
continue
if update.message.from_user:
user = update.message.from_user.username
# sometimes there's no user. weird, but it happens
if not user:
user = update.message.from_user.first_name
# sometimes there's no user. weird, but it happens
elif update.message['from']:
user = str(update.message['from'].first_name)
if update.message.audio or update.message.document or \ if update.message.audio or update.message.document or \
update.message.photo or update.message.video \ update.message.photo or update.message.video \
or update.message.voice or update.message.sticker: or update.message.voice:
# proceed only if http upload is available
# proceed only if http upload is available
if self.max_size is not None: if self.max_size is not None:
if update.message.audio: if update.message.audio:
d_file = update.message.audio d_file = update.message.audio
@ -152,18 +119,13 @@ class Jabbergram(sleekxmpp.ClientXMPP):
d_file = update.message.voice d_file = update.message.voice
ext = '.ogg' ext = '.ogg'
size = d_file.file_size size = d_file.file_size
elif update.message.sticker: if self.max_size >= size:
d_file = update.message.sticker
ext = '.png'
size = d_file.file_size
if self.max_size >= int(size):
t_file = self.bot.getFile(d_file.file_id) t_file = self.bot.getFile(d_file.file_id)
f_name = '/tmp/' + d_file.file_id + ext name = '/tmp/' + d_file.file_id + ext
t_file.download(f_name) t_file.download(name)
url = self.http_upload.upload( url = self.http_upload.upload(
self.component, self.component,
self.verify_ssl, '', name, size)
f_name, size)
if update.message.caption: if update.message.caption:
message = update.message.caption + ' ' message = update.message.caption + ' '
@ -172,65 +134,52 @@ class Jabbergram(sleekxmpp.ClientXMPP):
message += url message += url
else: else:
message = 'A file has been uploaded to Telegr'\ message = 'A file has been uploaded to Telegra'
'am, but is too big.' 'm, but is too big.'
else: else:
message = 'A file has been uploaded to Telegram,'\ message = 'A file has been uploaderd to Telegram, '
'but the XMPP server doesn\'t support H'\ 'but the XMPP server doesn\'t support HTTP Upload.'
'TTP Upload.'
elif update.message.new_chat_members: elif update.message.new_chat_member:
message = 'This user has joined the group.' message = 'This user has joined the group.'
elif update.message.left_chat_member: elif update.message.left_chat_member:
message = 'This user has left the group.' message = 'This user has left the group.'
elif update.message.new_chat_title: elif update.message.new_chat_title:
message = 'The group\'s title has changed: ' + \ message = 'The group\'s title has changed: '+ \
update.message.new_chat_title update.message.new_chat_title
elif update.message.new_chat_photo: elif update.message.new_chat_photo:
message = 'The group\'s photo has changed.' message = 'The group\'s photo haschanged.'
else: else:
if update.message.reply_to_message: message = update.message.text
name = update.message.reply_to_message.from_user\
.username
if name != self.bot.username:
message = name + ': ' + \
update.message.reply_to_message.text
else:
message = update.message.reply_to_message.text
else:
message = update.message.text
if name: user = str(update.message.from_user.username)
msg = message + ' <- ' + user + ": " + \
update.message.text
else:
msg = user + ": " + message
if update.message.chat.type == 'supergroup' and \ # sometimes there's no user. weird, but it happens
update.message.chat.username: if not user:
chat = '@' + update.message.chat.username user = str(update.message.from_user.first_name)
else:
chat = str(update.message.chat.id)
if chat not in self.groups: # even weirder is that username or first_name exists
chat = str(update.message.chat_id) # let's take last_name
if not user:
user = str(update.message.from_user.last_name)
if message and chat in self.groups: msg = user + ": " + message
index = self.groups.index(chat) chat_id = update.message.chat_id
if message and str(chat_id) in self.groups:
index = self.groups.index(str(chat_id))
receiver = self.muc_rooms[index] receiver = self.muc_rooms[index]
if chat in self.telegram_users: if chat_id in self.telegram_users:
if user not in self.telegram_users[chat]: if user not in self.telegram_users[chat_id]:
self.telegram_users[chat] += ' ' + user self.telegram_users[chat_id] += ' ' + user
else: else:
self.telegram_users[chat] = ' ' + user self.telegram_users[chat_id] = ' ' + user
if message == '.users': if message == '.users':
self.say_users('telegram', receiver, chat) index = self.groups.index(str(chat_id))
elif message == '.help': muc = self.muc_rooms[index]
self.say_help('telegram', receiver, chat) self.say_users('telegram', muc, chat_id)
elif message == '.where':
self.say_where('telegram', receiver, chat)
else: else:
self.send_message(mto=receiver, mbody=msg, self.send_message(mto=receiver, mbody=msg,
mtype='groupchat') mtype='groupchat')
@ -240,7 +189,7 @@ class Jabbergram(sleekxmpp.ClientXMPP):
print(e) print(e)
sleep(1) sleep(1)
except Unauthorized as e: except Unauthorized:
print(e) print(e)
sleep(1) sleep(1)
@ -249,7 +198,6 @@ class Jabbergram(sleekxmpp.ClientXMPP):
print(e) print(e)
def start(self, event): def start(self, event):
"""Does some initial setup for XMPP and joins all mucs."""
self.get_roster() self.get_roster()
self.send_presence() self.send_presence()
@ -257,23 +205,18 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.plugin['xep_0045'].joinMUC(muc, self.nick, wait=True) self.plugin['xep_0045'].joinMUC(muc, self.nick, wait=True)
def muc_message(self, msg): def muc_message(self, msg):
"""Muc message's handler."""
muc_room = str(msg['from']).split('/')[0] muc_room = str(msg['from']).split('/')[0]
index = self.muc_rooms.index(muc_room) index = self.muc_rooms.index(muc_room)
tg_group = self.groups[index] tg_group = self.groups[index]
if msg['body'] == '.users': if msg['body'] == '.users':
self.say_users('xmpp', muc_room, tg_group) self.say_users('xmpp', muc_room, tg_group)
elif msg['body'] == '.help':
self.say_help('xmpp', muc_room, tg_group)
elif msg['body'] == '.where':
self.say_where('xmpp', muc_room, tg_group)
elif msg['mucnick'] != self.nick: elif msg['mucnick'] != self.nick:
message = str(msg['from']).split('/')[1] + ': ' + str(msg['body']) message = str(msg['from']).split('/')[1] + ': ' + str(msg['body'])
self.bot.sendMessage(tg_group, text=message) self.bot.sendMessage(tg_group, text=message)
def muc_online(self, presence): def muc_online(self, presence):
"""Muc presence's handler."""
user = presence['muc']['nick'] user = presence['muc']['nick']
muc = presence['from'].bare muc = presence['from'].bare
@ -284,7 +227,6 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.xmpp_users[muc] = [presence['muc']['nick']] self.xmpp_users[muc] = [presence['muc']['nick']]
def muc_offline(self, presence): def muc_offline(self, presence):
"""Muc presence's handler."""
user = presence['muc']['nick'] user = presence['muc']['nick']
muc = presence['from'].bare muc = presence['from'].bare
@ -292,58 +234,39 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.xmpp_users[muc].remove(presence['muc']['nick']) self.xmpp_users[muc].remove(presence['muc']['nick'])
def say_users(self, service, muc, group): def say_users(self, service, muc, group):
"""It returns the users on XMPP or Telegram.""" xmpp_users = ""
if service == 'xmpp': tg_users = ""
if group in self.telegram_users: group = int(group)
tg_users = self.telegram_users[group]
else:
tg_users = ""
msg = 'Telegram Users:' + tg_users if muc in self.xmpp_users:
for i in self.xmpp_users[muc]:
self.send_message(mto=muc, mbody=msg, mtype='groupchat') xmpp_users = xmpp_users + ' _' + i
else:
elif service == 'telegram':
xmpp_users = "" xmpp_users = ""
if muc in self.xmpp_users:
for i in self.xmpp_users[muc]:
xmpp_users = xmpp_users + ' ' + i
else:
xmpp_users = ""
msg = 'XMPP Users:' + xmpp_users msg1 = 'XMPP Users:' + xmpp_users
self.bot.sendMessage(group, text=msg)
if group in self.telegram_users:
tg_users = self.telegram_users[group]
else:
tg_users = ""
msg2 = 'Telegram Users:' + tg_users
message = msg1 + '\n' + msg2
def say_help(self, service, muc, group):
"""Help command."""
msg = 'Hi, I\'m ' + self.bot.username + '. I have two commands : ".us'\
'ers" and ".where".'
if service == 'xmpp': if service == 'xmpp':
self.send_message(mto=muc, mbody=msg, mtype='groupchat') self.send_message(mto=muc, mbody=message, mtype='groupchat')
elif service == 'telegram':
self.bot.sendMessage(group, text=msg)
def say_where(self, service, muc, group):
"""Returns Telegram's group location if it's public."""
if service == 'xmpp':
if '@' in group:
msg = 'I\'m on http://telegram.me/' + group.split('@')[1] + '.'
else:
msg = 'Sorry, I\'m on a private group, you\'ll have to ask fo'\
'r an invitation.'
self.send_message(mto=muc, mbody=msg, mtype='groupchat')
elif service == 'telegram': elif service == 'telegram':
msg = 'I\'m on ' + muc + '.' self.bot.sendMessage(group, text=message)
self.bot.sendMessage(group, text=msg)
class HttpUpload(): class HttpUpload():
"""HTTP upload main class."""
def __init__(self, parent_self): def __init__(self, parent_self):
"""Init... Yep."""
self.parent_self = parent_self self.parent_self = parent_self
def discovery(self): def discovery(self):
"""Discovers all server's components."""
disco = sleekxmpp.basexmpp.BaseXMPP.Iq(self.parent_self) disco = sleekxmpp.basexmpp.BaseXMPP.Iq(self.parent_self)
disco['query'] = "http://jabber.org/protocol/disco#items" disco['query'] = "http://jabber.org/protocol/disco#items"
disco['type'] = 'get' disco['type'] = 'get'
@ -367,18 +290,17 @@ class Jabbergram(sleekxmpp.ClientXMPP):
return http_upload_component return http_upload_component
def disco_info(self, component): def disco_info(self, component):
"""Discovers HTTP upload components attributes."""
info = sleekxmpp.basexmpp.BaseXMPP.Iq(self.parent_self) info = sleekxmpp.basexmpp.BaseXMPP.Iq(self.parent_self)
info['query'] = "http://jabber.org/protocol/disco#info" info['query'] = "http://jabber.org/protocol/disco#info"
info['type'] = 'get' info['type'] = 'get'
info['from'] = self.parent_self.jid info['from'] = self.parent_self.jid
info['to'] = component info['to'] = component
response = str(info.send(timeout=30))
return response return str(info.send(timeout=30))
def upload(self, component, verify_ssl, u_file, size): def upload(self, component, verify_ssl, u_file, size):
"""Uploads to HTTP upload."""
peticion = Request() peticion = Request()
peticion['filename'] = u_file.split('/')[-1] peticion['filename'] = u_file.split('/')[-1]
peticion['size'] = str(size) peticion['size'] = str(size)
@ -394,6 +316,7 @@ class Jabbergram(sleekxmpp.ClientXMPP):
xml = minidom.parseString(str(send)) xml = minidom.parseString(str(send))
put_url = xml.getElementsByTagName('put')[0].firstChild.data put_url = xml.getElementsByTagName('put')[0].firstChild.data
verify_ssl = ''
if verify_ssl == 'False': if verify_ssl == 'False':
req = requests.put(put_url, data=open(u_file, 'rb'), req = requests.put(put_url, data=open(u_file, 'rb'),
verify=False) verify=False)
@ -424,10 +347,8 @@ if __name__ == '__main__':
nick = config[3] nick = config[3]
token = config[4] token = config[4]
groups = config[5] groups = config[5]
verify_ssl = config[6]
xmpp = Jabbergram(jid, password, muc_rooms, nick, token, groups, xmpp = Jabbergram(jid, password, muc_rooms, nick, token, groups)
verify_ssl)
xmpp.register_plugin('xep_0045') xmpp.register_plugin('xep_0045')
if xmpp.connect(): if xmpp.connect():
@ -435,3 +356,5 @@ if __name__ == '__main__':
print("Done") print("Done")
else: else:
print("Unable to connect.") print("Unable to connect.")
# Vols un gram nen?

View File

@ -1,3 +1,3 @@
sleekxmpp >= 1.3.2 sleekxmpp >= 1.3.1
python-telegram-bot >= 6.1.0 python-telegram-bot >= 4.0.3
requests >= 2.11.1 requests >= 2.11.1

View File

@ -30,9 +30,6 @@ printed = []
while True: while True:
try: try:
for update in bot.getUpdates(offset=update_id, timeout=10): for update in bot.getUpdates(offset=update_id, timeout=10):
if update.edited_message:
update_id = update.update_id + 1
continue
chat_id = update.message.chat_id chat_id = update.message.chat_id
chat_title = update.message chat_title = update.message
if chat_id not in printed: if chat_id not in printed:

View File

@ -2,7 +2,7 @@
from setuptools import setup from setuptools import setup
VERSION = '0.1.8' VERSION = '0.1.6'
setup(name='jabbergram', setup(name='jabbergram',
version=VERSION, version=VERSION,
@ -10,13 +10,13 @@ setup(name='jabbergram',
long_description=open('README.rst', encoding='utf-8').read(), long_description=open('README.rst', encoding='utf-8').read(),
author='drymer', author='drymer',
author_email='drymer@autistici.org', author_email='drymer@autistici.org',
url='http://git.daemons.it/drymer/jabbergram/about/', url='http://daemons.cf/cgit/jabbergram/about/',
download_url='https://git.daemons.it/drymer/jabbergram/archive/' + VERSION + '.tar.gz', download_url='http://daemons.cf/cgit/jabbergram/snapshot/jabbergram-' + VERSION + '.tar.gz',
scripts=['jabbergram.py'], scripts=['jabbergram.py'],
license="GPLv3", license="GPLv3",
install_requires=[ install_requires=[
"sleekxmpp>=1.3.1", "sleekxmpp>=1.3.1",
"python-telegram-bot>=6.0.1", "python-telegram-bot>=4.0.3",
"requests>=2.11.1", "requests>=2.11.1",
], ],
classifiers=["Development Status :: 4 - Beta", classifiers=["Development Status :: 4 - Beta",