Compare commits
9 Commits
Author | SHA1 | Date |
---|---|---|
Hemna | 9f87a8fec9 | |
Hemna | 827832ae33 | |
Hemna | 25e18a55d2 | |
Hemna | 108ea07f60 | |
Hemna | 547c326a09 | |
Hemna | fa8ae88c35 | |
Hemna | 1dc0744ac0 | |
Hemna | cac8807074 | |
Hemna | da0d448767 |
20
ChangeLog
20
ChangeLog
|
@ -1,9 +1,27 @@
|
|||
CHANGES
|
||||
=======
|
||||
|
||||
* First version working
|
||||
v0.1.3
|
||||
------
|
||||
|
||||
* remove trace
|
||||
|
||||
v0.1.2
|
||||
------
|
||||
|
||||
* for v0.1.2
|
||||
* for v0.1.1
|
||||
* Use the pbr version of the package as plugin version
|
||||
|
||||
v0.1.1
|
||||
------
|
||||
|
||||
* Updated Changelog for v0.1.1
|
||||
* Fixed a 100% CPU utilization issue
|
||||
|
||||
v0.1.0
|
||||
------
|
||||
|
||||
* Updated Changelog
|
||||
* First version working
|
||||
* Initial commit
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
import pbr.version
|
||||
|
||||
|
||||
__version__ = pbr.version.VersionInfo("aprsd_telegram_plugin").version_string()
|
|
@ -0,0 +1,9 @@
|
|||
import logging
|
||||
|
||||
from aprsd_twitter_plugin.conf import twitter
|
||||
from oslo_config import cfg
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
twitter.register_opts(CONF)
|
|
@ -0,0 +1,80 @@
|
|||
# Copyright 2015 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
This is the single point of entry to generate the sample configuration
|
||||
file for Nova. It collects all the necessary info from the other modules
|
||||
in this package. It is assumed that:
|
||||
|
||||
* every other module in this package has a 'list_opts' function which
|
||||
return a dict where
|
||||
* the keys are strings which are the group names
|
||||
* the value of each key is a list of config options for that group
|
||||
* the nova.conf package doesn't have further packages with config options
|
||||
* this module is only used in the context of sample file generation
|
||||
"""
|
||||
|
||||
import collections
|
||||
import importlib
|
||||
import os
|
||||
import pkgutil
|
||||
|
||||
|
||||
LIST_OPTS_FUNC_NAME = "list_opts"
|
||||
|
||||
|
||||
def _tupleize(dct):
|
||||
"""Take the dict of options and convert to the 2-tuple format."""
|
||||
return [(key, val) for key, val in dct.items()]
|
||||
|
||||
|
||||
def list_opts():
|
||||
opts = collections.defaultdict(list)
|
||||
module_names = _list_module_names()
|
||||
imported_modules = _import_modules(module_names)
|
||||
_append_config_options(imported_modules, opts)
|
||||
return _tupleize(opts)
|
||||
|
||||
|
||||
def _list_module_names():
|
||||
module_names = []
|
||||
package_path = os.path.dirname(os.path.abspath(__file__))
|
||||
for _, modname, ispkg in pkgutil.iter_modules(path=[package_path]):
|
||||
if modname == "opts" or ispkg:
|
||||
continue
|
||||
else:
|
||||
module_names.append(modname)
|
||||
return module_names
|
||||
|
||||
|
||||
def _import_modules(module_names):
|
||||
imported_modules = []
|
||||
for modname in module_names:
|
||||
mod = importlib.import_module("aprsd_telegram_plugin.conf." + modname)
|
||||
if not hasattr(mod, LIST_OPTS_FUNC_NAME):
|
||||
msg = "The module 'aprsd_telegram_plugin.conf.%s' should have a '%s' "\
|
||||
"function which returns the config options." % \
|
||||
(modname, LIST_OPTS_FUNC_NAME)
|
||||
raise Exception(msg)
|
||||
else:
|
||||
imported_modules.append(mod)
|
||||
return imported_modules
|
||||
|
||||
|
||||
def _append_config_options(imported_modules, config_options):
|
||||
for mod in imported_modules:
|
||||
configs = mod.list_opts()
|
||||
for key, val in configs.items():
|
||||
config_options[key].extend(val)
|
|
@ -0,0 +1,44 @@
|
|||
from oslo_config import cfg
|
||||
|
||||
|
||||
telegram_group = cfg.OptGroup(
|
||||
name="aprsd_telegram_plugin",
|
||||
title="APRSD Telegram Plugin settings",
|
||||
)
|
||||
|
||||
telegram_opts = [
|
||||
cfg.StrOpt(
|
||||
"callsign",
|
||||
help="Callsign allowed to use Telegram! "
|
||||
"For example, if you set this to WB4BOR then any"
|
||||
"callsign starting with WB4BOR will be allowed to use this."
|
||||
"This way WB4BOR-1 can tweet from this instance.",
|
||||
),
|
||||
cfg.StrOpt(
|
||||
"apiKey",
|
||||
help="Your twitter apiKey"
|
||||
"Information for creating your api keys is here: "
|
||||
"https://developer.twitter.com/en/docs/authentication/oauth-1-0a/api-key-and-secret",
|
||||
),
|
||||
cfg.ListOpt(
|
||||
"shortcuts",
|
||||
help="List of shortcuts for sending telegram messages "
|
||||
"For Exmaple: wb=hemna6969,cl=craigerl\n"
|
||||
"Means use 'wb' to send a telegram message to hemna6969",
|
||||
),
|
||||
]
|
||||
|
||||
ALL_OPTS = (
|
||||
telegram_opts
|
||||
)
|
||||
|
||||
|
||||
def register_opts(cfg):
|
||||
cfg.register_group(telegram_group)
|
||||
cfg.register_opts(ALL_OPTS, group=telegram_group)
|
||||
|
||||
|
||||
def list_opts():
|
||||
return {
|
||||
telegram_group.name: ALL_OPTS,
|
||||
}
|
|
@ -1,11 +1,19 @@
|
|||
import datetime
|
||||
import logging
|
||||
import threading
|
||||
import time
|
||||
|
||||
from aprsd import messaging, objectstore, plugin, threads, trace
|
||||
from aprsd import conf # noqa
|
||||
from aprsd import packets, plugin, threads
|
||||
from aprsd.utils import objectstore
|
||||
from oslo_config import cfg
|
||||
from telegram.ext import Filters, MessageHandler, Updater
|
||||
|
||||
import aprsd_telegram_plugin
|
||||
from aprsd_telegram_plugin import conf # noqa
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger("APRSD")
|
||||
|
||||
|
||||
|
@ -20,17 +28,15 @@ class TelegramUsers(objectstore.ObjectStoreMixin):
|
|||
"""
|
||||
_instance = None
|
||||
data = {}
|
||||
config = None
|
||||
_shortcuts = {}
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
if cls._instance is None:
|
||||
cls._instance = super().__new__(cls)
|
||||
cls._instance.lock = threading.Lock()
|
||||
cls._instance.config = kwargs["config"]
|
||||
cls._instance.data = {}
|
||||
if kwargs["config"].exists("services.telegram.shortcuts"):
|
||||
cls._instance._shortcuts = kwargs["config"].get("services.telegram.shortcuts")
|
||||
if CONF.aprsd_telegram_plugin.shortcuts:
|
||||
cls._instance._shortcuts = CONF.aprsd_telegram_plugin.shortcuts
|
||||
else:
|
||||
cls._instance._shortcuts = None
|
||||
cls._instance._init_store()
|
||||
|
@ -64,7 +70,7 @@ class TelegramUsers(objectstore.ObjectStoreMixin):
|
|||
|
||||
class TelegramChatPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||
|
||||
version = "1.0"
|
||||
version = aprsd_telegram_plugin.__version__
|
||||
# Look for any command that starts with w or W
|
||||
command_regex = "^[tT][gG]"
|
||||
# the command is for ?
|
||||
|
@ -77,39 +83,48 @@ class TelegramChatPlugin(plugin.APRSDRegexCommandPluginBase):
|
|||
_help = [
|
||||
"telegram: Chat with a user on telegram Messenger.",
|
||||
"telegram: username has to message you first."
|
||||
"tg: Send tg <shortcut/username> <message>",
|
||||
"tg: Send tg <username> <message>",
|
||||
]
|
||||
return _help
|
||||
|
||||
def setup(self):
|
||||
self.enabled = True
|
||||
# Do some checks here?
|
||||
try:
|
||||
self.config.check_option(["services", "telegram", "apiKey"])
|
||||
except Exception as ex:
|
||||
if not CONF.aprsd_telegram_plugin.apiKey:
|
||||
LOG.error(f"Failed to find config telegram:apiKey {ex}")
|
||||
self.enabled = False
|
||||
return
|
||||
|
||||
token = self.config.get("services.telegram.apiKey")
|
||||
token = CONF.aprsd_telegram_plugin.apiKey
|
||||
|
||||
self.users = TelegramUsers(config=self.config)
|
||||
self.users = TelegramUsers()
|
||||
self.users.load()
|
||||
|
||||
# self.bot = telegram.Bot(token=token)
|
||||
# LOG.info(self.bot.get_me())
|
||||
self.updater = Updater(
|
||||
token=token,
|
||||
use_context=True,
|
||||
persistence=False,
|
||||
)
|
||||
self.dispatcher = self.updater.dispatcher
|
||||
self.dispatcher.add_handler(
|
||||
MessageHandler(
|
||||
Filters.text & (~Filters.command),
|
||||
self.message_handler,
|
||||
),
|
||||
)
|
||||
LOG.info("Starting up Updater")
|
||||
try:
|
||||
self.updater = Updater(
|
||||
token=token,
|
||||
use_context=True,
|
||||
persistence=False,
|
||||
)
|
||||
except Exception as ex:
|
||||
self.enabled = False
|
||||
LOG.exception(ex)
|
||||
LOG.info("Starting up Dispatcher")
|
||||
|
||||
try:
|
||||
self.dispatcher = self.updater.dispatcher
|
||||
self.dispatcher.add_handler(
|
||||
MessageHandler(
|
||||
Filters.text & (~Filters.command),
|
||||
self.message_handler,
|
||||
),
|
||||
)
|
||||
except Exception as ex:
|
||||
self.enabled = False
|
||||
LOG.exception(ex)
|
||||
|
||||
def message_handler(self, update, context):
|
||||
"""This is called when a telegram users texts the bot."""
|
||||
|
@ -118,7 +133,7 @@ class TelegramChatPlugin(plugin.APRSDRegexCommandPluginBase):
|
|||
# LOG.info(f"Chat {update.message.chat}")
|
||||
# LOG.info(f"From {update.message.from.username} : ")
|
||||
fromcall = self.config.get("aprs.login")
|
||||
tocall = self.config.get("ham.callsign")
|
||||
tocall = CONF.callsign
|
||||
|
||||
if update.message.chat.type == "private":
|
||||
LOG.info(f"Username {update.message.chat.username} - ID {update.message.chat.id}")
|
||||
|
@ -129,28 +144,36 @@ class TelegramChatPlugin(plugin.APRSDRegexCommandPluginBase):
|
|||
self.users[update.message.chat.username] = update.message.chat.id
|
||||
# LOG.debug(self.users)
|
||||
# LOG.info(f"{message}")
|
||||
msg = messaging.TextMessage(fromcall, tocall, message)
|
||||
msg.send()
|
||||
pkt = packets.MessagePacket(
|
||||
from_call=fromcall,
|
||||
to_call=tocall,
|
||||
message_text=message,
|
||||
)
|
||||
pkt.send()
|
||||
elif update.message.chat.type == "group":
|
||||
group_name = "noidea"
|
||||
message = "TelegramGroup({}): {}".format(
|
||||
group_name,
|
||||
update.message.text,
|
||||
)
|
||||
msg = messaging.TextMessage(fromcall, tocall, message)
|
||||
msg.send()
|
||||
pkt = packets.MessagePacket(
|
||||
from_call=fromcall,
|
||||
to_call=tocall,
|
||||
message_text=message,
|
||||
)
|
||||
pkt.send()
|
||||
|
||||
def create_threads(self):
|
||||
if self.enabled:
|
||||
return TelegramThread(self.config, self.updater)
|
||||
LOG.info("Starting TelegramThread")
|
||||
return TelegramThread(self.updater)
|
||||
|
||||
@trace.trace
|
||||
def process(self, packet):
|
||||
"""This is called when a received packet matches self.command_regex."""
|
||||
LOG.info("TelegramChatPlugin Plugin")
|
||||
|
||||
from_callsign = packet.get("from")
|
||||
message = packet.get("message_text", None)
|
||||
from_callsign = packet.from_call
|
||||
message = packet.message_text
|
||||
|
||||
if self.enabled:
|
||||
# Now we can process
|
||||
|
@ -182,29 +205,34 @@ class TelegramChatPlugin(plugin.APRSDRegexCommandPluginBase):
|
|||
text=msg,
|
||||
)
|
||||
|
||||
return messaging.NULL_MESSAGE
|
||||
return packets.NULL_MESSAGE
|
||||
else:
|
||||
LOG.warning("TelegramChatPlugin is disabled.")
|
||||
return messaging.NULL_MESSAGE
|
||||
return packets.NULL_MESSAGE
|
||||
|
||||
|
||||
class TelegramThread(threads.APRSDThread):
|
||||
def __init__(self, config, updater):
|
||||
def __init__(self, updater):
|
||||
super().__init__(self.__class__.__name__)
|
||||
self.config = config
|
||||
self.past = datetime.datetime.now()
|
||||
self.updater = updater
|
||||
|
||||
def stop(self):
|
||||
self.thread_stop = True
|
||||
self.updater.stop()
|
||||
TelegramUsers(config=self.config).save()
|
||||
TelegramUsers().save()
|
||||
|
||||
def loop(self):
|
||||
"""We have to loop, so we can stop the thread upon CTRL-C"""
|
||||
self.updater.start_polling(
|
||||
timeout=2,
|
||||
drop_pending_updates=True,
|
||||
)
|
||||
try:
|
||||
self.updater.start_polling(
|
||||
timeout=2,
|
||||
drop_pending_updates=True,
|
||||
)
|
||||
except Exception as ex:
|
||||
LOG.exception(ex)
|
||||
return False
|
||||
# So we don't eat 100% CPU
|
||||
time.sleep(1)
|
||||
# so we can continue looping
|
||||
return True
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
pbr
|
||||
aprsd>=2.4.0
|
||||
aprsd>=3.0.0
|
||||
python-telegram-bot
|
||||
oslo.config
|
||||
|
|
Loading…
Reference in New Issue