Merge branch 'dev' of drymer/jabbergram into master

This commit is contained in:
drymer 2017-07-21 08:29:37 +02:00 committed by git
commit 2b47e3528d
7 changed files with 111 additions and 68 deletions

View File

@ -48,7 +48,7 @@ Install via pip:
Clone the repository:
$ git clone git://daemons.cf/jabbergram
$ git clone https://git.daemons.it/drymer/jabbergram
$ cd jabbergram
$ su -c "pip3 install -r requirements.txt"
$ su -c "python3 setup.py install"
@ -128,9 +128,9 @@ Instalar a través de `pip`:
Clonar el repositorio:
$ git clone git://daemons.cf/jabbergram
$ git clone https://git.daemons.it/drymer/jabbergram
$ cd jabbergram
$ su -c "pip3 instalar -r requirements.txt"
$ su -c "pip3 install -r requirements.txt"
$ su -c "python3 setup.py install"
### 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
# 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 `Telegrama` 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 `Telegram` 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:
@ -173,7 +173,7 @@ Sólo puede haber un archivo de configuración. Esto es debido a que sólo puede
token = jabbergramBotTokken
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".
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.
### Licencia<a id="orgheadline11"></a>

View File

@ -14,7 +14,7 @@
Clone the repository:
#+BEGIN_SRC sh
$ git clone git://daemons.cf/jabbergram
$ git clone https://git.daemons.it/drymer/jabbergram
$ cd jabbergram
$ su -c "pip3 install -r requirements.txt"
$ su -c "python3 setup.py install"
@ -93,9 +93,9 @@
Clonar el repositorio:
#+BEGIN_SRC sh
$ git clone git://daemons.cf/jabbergram
$ git clone https://git.daemons.it/drymer/jabbergram
$ cd jabbergram
$ su -c "pip3 instalar -r requirements.txt"
$ su -c "pip3 install -r requirements.txt"
$ su -c "python3 setup.py install"
#+END_SRC
*** Configuración
@ -111,7 +111,7 @@
# Ahora hay que pulsar desactivar
#+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 =Telegrama= 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 =Telegram= 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:
@ -141,7 +141,7 @@
group = -10293943920 120301203
#+END_SRC
De este modo, el muc "exampleMuc@muc.nope.org" se sincronizará con el grupo "-10293943920", y "segunda@muc.sip.org" con "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.
*** Licencia
#+BEGIN_SRC text
This program is free software: you can redistribute it and / or modify

View File

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

View File

@ -1,33 +1,42 @@
#!/usr/bin/env python3
# -*- 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:
import requests
except:
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
logging.error("HTTP Upload support disabled.")
class Request(ElementBase):
"""Special class to create http_upload requests."""
namespace = 'urn:xmpp:http:upload'
name = 'request'
plugin_attrib = 'request'
interfaces = set(('filename', 'size'))
sub_interfaces = interfaces
class Jabbergram(sleekxmpp.ClientXMPP):
def __init__(self, jid, password, rooms, nick, token, groups):
"""Main object."""
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
super(Jabbergram, self).__init__(jid, password)
self.add_event_handler('session_start', self.start)
@ -38,6 +47,7 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.token = token
self.xmpp_users = {}
self.jid = jid
self.verify_ssl = verify_ssl
for muc in self.muc_rooms:
self.add_event_handler("muc::%s::got_online" % muc,
@ -49,7 +59,6 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.groups = groups.split()
self.bot = telegram.Bot(self.token)
self.telegram_users = {}
self.group_name = {}
# initialize http upload on a thread since its needed to be connected
# to xmpp
@ -66,6 +75,11 @@ class Jabbergram(sleekxmpp.ClientXMPP):
'connected')
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.component = self.http_upload.discovery()
@ -85,8 +99,8 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.max_size = None
def read_tg(self):
"""Main telegram function."""
update_id = 0
name = ''
# wait until http_upload has been tested
sleep(5)
@ -94,12 +108,29 @@ class Jabbergram(sleekxmpp.ClientXMPP):
try:
for update in self.bot.getUpdates(offset=update_id,
timeout=10):
if not self.group_name:
self.group_name = update.message.chat.username
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 \
update.message.photo or update.message.video \
or update.message.voice or update.message.sticker:
# proceed only if http upload is available
if self.max_size is not None:
if update.message.audio:
d_file = update.message.audio
@ -121,13 +152,18 @@ class Jabbergram(sleekxmpp.ClientXMPP):
d_file = update.message.voice
ext = '.ogg'
size = d_file.file_size
if self.max_size >= size:
elif update.message.sticker:
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)
f_name = '/tmp/' + d_file.file_id + ext
t_file.download(f_name)
url = self.http_upload.upload(
self.component,
'', f_name, size)
self.component,
self.verify_ssl,
f_name, size)
if update.message.caption:
message = update.message.caption + ' '
@ -139,16 +175,16 @@ class Jabbergram(sleekxmpp.ClientXMPP):
message = 'A file has been uploaded to Telegr'\
'am, but is too big.'
else:
message = 'A file has been uploaderd to Telegram,'\
message = 'A file has been uploaded to Telegram,'\
'but the XMPP server doesn\'t support H'\
'TTP Upload.'
elif update.message.new_chat_member:
elif update.message.new_chat_members:
message = 'This user has joined the group.'
elif update.message.left_chat_member:
message = 'This user has left the group.'
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
elif update.message.new_chat_photo:
message = 'The group\'s photo has changed.'
@ -161,28 +197,21 @@ class Jabbergram(sleekxmpp.ClientXMPP):
update.message.reply_to_message.text
else:
message = update.message.reply_to_message.text
message = message + ' <- ' + update.message.text
else:
message = update.message.text
user = str(update.message.from_user.username)
# sometimes there's no user. weird, but it happens
if not user:
user = str(update.message.from_user.first_name)
# even weirder is that username or first_name exists
# let's take last_name
if not user:
user = str(update.message.from_user.last_name)
# Don't add name first if it's a reply
if name:
msg = message
msg = message + ' <- ' + user + ": " + \
update.message.text
else:
msg = user + ": " + message
chat = '@' + update.message.chat.username
if update.message.chat.type == 'supergroup' and \
update.message.chat.username:
chat = '@' + update.message.chat.username
else:
chat = str(update.message.chat.id)
if chat not in self.groups:
chat = str(update.message.chat_id)
@ -194,15 +223,14 @@ class Jabbergram(sleekxmpp.ClientXMPP):
if user not in self.telegram_users[chat]:
self.telegram_users[chat] += ' ' + user
else:
self.telegram_users[chat] = ' ' + user
if message == '.users':
self.say_users('telegram', muc, chat)
self.say_users('telegram', receiver, chat)
elif message == '.help':
self.say_help('telegram', muc, chat)
self.say_help('telegram', receiver, chat)
elif message == '.where':
self.say_where('telegram', muc, chat)
self.say_where('telegram', receiver, chat)
else:
self.send_message(mto=receiver, mbody=msg,
mtype='groupchat')
@ -212,7 +240,7 @@ class Jabbergram(sleekxmpp.ClientXMPP):
print(e)
sleep(1)
except Unauthorized:
except Unauthorized as e:
print(e)
sleep(1)
@ -221,6 +249,7 @@ class Jabbergram(sleekxmpp.ClientXMPP):
print(e)
def start(self, event):
"""Does some initial setup for XMPP and joins all mucs."""
self.get_roster()
self.send_presence()
@ -228,6 +257,7 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.plugin['xep_0045'].joinMUC(muc, self.nick, wait=True)
def muc_message(self, msg):
"""Muc message's handler."""
muc_room = str(msg['from']).split('/')[0]
index = self.muc_rooms.index(muc_room)
tg_group = self.groups[index]
@ -243,6 +273,7 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.bot.sendMessage(tg_group, text=message)
def muc_online(self, presence):
"""Muc presence's handler."""
user = presence['muc']['nick']
muc = presence['from'].bare
@ -253,6 +284,7 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.xmpp_users[muc] = [presence['muc']['nick']]
def muc_offline(self, presence):
"""Muc presence's handler."""
user = presence['muc']['nick']
muc = presence['from'].bare
@ -260,6 +292,7 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.xmpp_users[muc].remove(presence['muc']['nick'])
def say_users(self, service, muc, group):
"""It returns the users on XMPP or Telegram."""
if service == 'xmpp':
if group in self.telegram_users:
tg_users = self.telegram_users[group]
@ -282,6 +315,7 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.bot.sendMessage(group, text=msg)
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':
@ -290,9 +324,10 @@ class Jabbergram(sleekxmpp.ClientXMPP):
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 self.group_name:
msg = 'I\'m on http://telegram.me/' + self.group_name + '.'
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.'
@ -302,11 +337,13 @@ class Jabbergram(sleekxmpp.ClientXMPP):
self.bot.sendMessage(group, text=msg)
class HttpUpload():
"""HTTP upload main class."""
def __init__(self, parent_self):
"""Init... Yep."""
self.parent_self = parent_self
def discovery(self):
"""Discovers all server's components."""
disco = sleekxmpp.basexmpp.BaseXMPP.Iq(self.parent_self)
disco['query'] = "http://jabber.org/protocol/disco#items"
disco['type'] = 'get'
@ -330,17 +367,18 @@ class Jabbergram(sleekxmpp.ClientXMPP):
return http_upload_component
def disco_info(self, component):
"""Discovers HTTP upload components attributes."""
info = sleekxmpp.basexmpp.BaseXMPP.Iq(self.parent_self)
info['query'] = "http://jabber.org/protocol/disco#info"
info['type'] = 'get'
info['from'] = self.parent_self.jid
info['to'] = component
response = str(info.send(timeout=30))
return str(info.send(timeout=30))
return response
def upload(self, component, verify_ssl, u_file, size):
"""Uploads to HTTP upload."""
peticion = Request()
peticion['filename'] = u_file.split('/')[-1]
peticion['size'] = str(size)
@ -356,7 +394,7 @@ class Jabbergram(sleekxmpp.ClientXMPP):
xml = minidom.parseString(str(send))
put_url = xml.getElementsByTagName('put')[0].firstChild.data
if verify_ssl == '' or verif_ssl == 'False':
if verify_ssl == 'False':
req = requests.put(put_url, data=open(u_file, 'rb'),
verify=False)
else:
@ -386,8 +424,10 @@ if __name__ == '__main__':
nick = config[3]
token = config[4]
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')
if xmpp.connect():

View File

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

View File

@ -30,6 +30,9 @@ printed = []
while True:
try:
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_title = update.message
if chat_id not in printed:

View File

@ -10,8 +10,8 @@ setup(name='jabbergram',
long_description=open('README.rst', encoding='utf-8').read(),
author='drymer',
author_email='drymer@autistici.org',
url='http://daemons.cf/cgit/jabbergram/about/',
download_url='http://daemons.cf/cgit/jabbergram/snapshot/jabbergram-' + VERSION + '.tar.gz',
url='http://git.daemons.it/drymer/jabbergram/about/',
download_url='https://git.daemons.it/drymer/jabbergram/archive/' + VERSION + '.tar.gz',
scripts=['jabbergram.py'],
license="GPLv3",
install_requires=[