mirror of
https://github.com/hemna/aprsd-twitter-plugin.git
synced 2024-11-21 15:51:56 -05:00
Update for aprsd 3.0.0
This patch updates for using the oslo_config style CONF and declares the plugin config vars
This commit is contained in:
parent
185d40a06e
commit
d51347f48e
10
aprsd_twitter_plugin/conf/__init__.py
Normal file
10
aprsd_twitter_plugin/conf/__init__.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
|
||||||
|
from aprsd_twitter_plugin.conf import twitter
|
||||||
|
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
|
||||||
|
twitter.register_opts(CONF)
|
80
aprsd_twitter_plugin/conf/opts.py
Normal file
80
aprsd_twitter_plugin/conf/opts.py
Normal file
@ -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_twitter_plugin.conf." + modname)
|
||||||
|
if not hasattr(mod, LIST_OPTS_FUNC_NAME):
|
||||||
|
msg = "The module 'aprsd_twitter_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)
|
57
aprsd_twitter_plugin/conf/twitter.py
Normal file
57
aprsd_twitter_plugin/conf/twitter.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
from oslo_config import cfg
|
||||||
|
|
||||||
|
|
||||||
|
twitter_group = cfg.OptGroup(
|
||||||
|
name="aprsd_twitter_plugin",
|
||||||
|
title="APRSD Twitter Plugin settings",
|
||||||
|
)
|
||||||
|
|
||||||
|
twitter_opts = [
|
||||||
|
cfg.StrOpt(
|
||||||
|
"callsign",
|
||||||
|
help="Callsign allowed to send tweets! "
|
||||||
|
"Any callsign starting with this will be allowed to tweet to"
|
||||||
|
"the configured twitter account. "
|
||||||
|
"For example, if you set this to WB4BOR then any"
|
||||||
|
"callsign starting with WB4BOR will be allowed to tweet."
|
||||||
|
"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.StrOpt(
|
||||||
|
"apiKey_secret",
|
||||||
|
help="Your twitter accounts apikey secret.",
|
||||||
|
),
|
||||||
|
cfg.StrOpt(
|
||||||
|
"access_token",
|
||||||
|
help="The twitter access_token for your Twitter account",
|
||||||
|
),
|
||||||
|
cfg.StrOpt(
|
||||||
|
"access_token_secret",
|
||||||
|
help="The twitter access token secret for your Twitter account",
|
||||||
|
),
|
||||||
|
cfg.BoolOpt(
|
||||||
|
"add_aprs_hashtag",
|
||||||
|
default=True,
|
||||||
|
help="Automatically add #aprs hash tag to every tweet?",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
ALL_OPTS = (
|
||||||
|
twitter_opts
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def register_opts(cfg):
|
||||||
|
cfg.register_group(twitter_group)
|
||||||
|
cfg.register_opts(ALL_OPTS, group=twitter_group)
|
||||||
|
|
||||||
|
|
||||||
|
def list_opts():
|
||||||
|
return {
|
||||||
|
twitter_group.name: ALL_OPTS,
|
||||||
|
}
|
@ -1,11 +1,15 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
import tweepy
|
import tweepy
|
||||||
from aprsd import packets, plugin
|
from aprsd import conf # noqa
|
||||||
|
from aprsd import plugin
|
||||||
|
from oslo_config import cfg
|
||||||
|
|
||||||
import aprsd_twitter_plugin
|
import aprsd_twitter_plugin
|
||||||
|
from aprsd_twitter_plugin import conf # noqa
|
||||||
|
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
LOG = logging.getLogger("APRSD")
|
LOG = logging.getLogger("APRSD")
|
||||||
|
|
||||||
|
|
||||||
@ -13,7 +17,8 @@ class SendTweetPlugin(plugin.APRSDRegexCommandPluginBase):
|
|||||||
|
|
||||||
version = aprsd_twitter_plugin.__version__
|
version = aprsd_twitter_plugin.__version__
|
||||||
# Look for any command that starts with tw or tW or TW or Tw
|
# Look for any command that starts with tw or tW or TW or Tw
|
||||||
command_regex = "^[tT][wW]"
|
# or case insensitive version of 'twitter'
|
||||||
|
command_regex = r"^([t][w]\s|twitter)"
|
||||||
# the command is for ?
|
# the command is for ?
|
||||||
command_name = "tweet"
|
command_name = "tweet"
|
||||||
|
|
||||||
@ -30,33 +35,52 @@ class SendTweetPlugin(plugin.APRSDRegexCommandPluginBase):
|
|||||||
# Do some checks here?
|
# Do some checks here?
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
|
|
||||||
|
if not CONF.aprsd_twitter_plugin.callsign:
|
||||||
|
LOG.error(
|
||||||
|
"No aprsd_twitter_pligin.callsign is set."
|
||||||
|
" Callsign is needed to allow tweets!",
|
||||||
|
)
|
||||||
|
self.enabled = False
|
||||||
|
|
||||||
# Ensure the access token exists.
|
# Ensure the access token exists.
|
||||||
if not self.config.exists("services.twitter.apiKey"):
|
if not CONF.aprsd_twitter_plugin.apiKey:
|
||||||
LOG.error("No services.twitter.apiKey exists. Plugin Disabled.")
|
LOG.error(
|
||||||
|
"No aprsd_twitter_plugin.apiKey is set!."
|
||||||
|
" Plugin Disabled.",
|
||||||
|
)
|
||||||
self.enabled = False
|
self.enabled = False
|
||||||
|
|
||||||
if not self.config.exists("services.twitter.apiKey_secret"):
|
if not CONF.aprsd_twitter_plugin.apiKey_secret:
|
||||||
LOG.error("No services.twitter.apiKey_secret exists. Plugin Disabled.")
|
LOG.error(
|
||||||
|
"No aprsd_twitter_plugin.apiKey_secret is set."
|
||||||
|
" Plugin Disabled.",
|
||||||
|
)
|
||||||
self.enabled = False
|
self.enabled = False
|
||||||
|
|
||||||
if not self.config.exists("services.twitter.access_token"):
|
if not CONF.aprsd_twitter_plugin.access_token:
|
||||||
LOG.error("No services.twitter.access_token exists. Plugin Disabled.")
|
LOG.error(
|
||||||
|
"No aprsd_twitter_plugin.access_token exists."
|
||||||
|
" Plugin Disabled.",
|
||||||
|
)
|
||||||
self.enabled = False
|
self.enabled = False
|
||||||
|
|
||||||
if not self.config.exists("services.twitter.access_token_secret"):
|
if not CONF.aprsd_twitter_plugin.access_token_secret:
|
||||||
LOG.error("No services.twitter.access_token_secret exists. Plugin Disabled.")
|
LOG.error(
|
||||||
|
"No aprsd_twitter_plugin.access_token_secret exists."
|
||||||
|
" Plugin Disabled.",
|
||||||
|
)
|
||||||
self.enabled = False
|
self.enabled = False
|
||||||
|
|
||||||
def _create_client(self):
|
def _create_client(self):
|
||||||
"""Create the twitter client object."""
|
"""Create the twitter client object."""
|
||||||
auth = tweepy.OAuthHandler(
|
auth = tweepy.OAuthHandler(
|
||||||
self.config.get("services.twitter.apiKey"),
|
CONF.aprsd_twitter_plugin.apiKey,
|
||||||
self.config.get("services.twitter.apiKey_secret"),
|
CONF.aprsd_twitter_plugin.apiKey_secret,
|
||||||
)
|
)
|
||||||
|
|
||||||
auth.set_access_token(
|
auth.set_access_token(
|
||||||
self.config.get("services.twitter.access_token"),
|
CONF.aprsd_twitter_plugin.access_token,
|
||||||
self.config.get("services.twitter.access_token_secret"),
|
CONF.aprsd_twitter_plugin.access_token_secret,
|
||||||
)
|
)
|
||||||
|
|
||||||
api = tweepy.API(
|
api = tweepy.API(
|
||||||
@ -86,23 +110,25 @@ class SendTweetPlugin(plugin.APRSDRegexCommandPluginBase):
|
|||||||
del message[0]
|
del message[0]
|
||||||
message = " ".join(message)
|
message = " ".join(message)
|
||||||
|
|
||||||
if self.enabled:
|
|
||||||
# Now we can process
|
# Now we can process
|
||||||
mycall = self.config["ham"]["callsign"]
|
auth_call = CONF.aprsd_twitter_plugin.callsign
|
||||||
|
|
||||||
# Only allow the owner of aprsd to send a tweet
|
# Only allow the owner of aprsd to send a tweet
|
||||||
if not from_callsign.startswith(mycall):
|
if not from_callsign.startswith(auth_call):
|
||||||
return "Unauthorized"
|
return f"{from_callsign} not authorized to tweet!"
|
||||||
|
|
||||||
client = self._create_client()
|
client = self._create_client()
|
||||||
if not client:
|
if not client:
|
||||||
LOG.error("No twitter client!!")
|
LOG.error("No twitter client!!")
|
||||||
return "Failed to Auth"
|
return "Failed to Auth"
|
||||||
|
|
||||||
|
if CONF.aprsd_twitter_plugin.add_aprs_hashtag:
|
||||||
|
message += (
|
||||||
|
" #aprs #aprsd #hamradio "
|
||||||
|
"https://github.com/hemna/aprsd-twitter-plugin"
|
||||||
|
)
|
||||||
|
|
||||||
# Now lets tweet!
|
# Now lets tweet!
|
||||||
client.update_status(message)
|
client.update_status(message)
|
||||||
|
|
||||||
return "Tweet sent!"
|
return "Tweet sent!"
|
||||||
else:
|
|
||||||
LOG.warning("SendTweetPlugin is disabled.")
|
|
||||||
return packets.NULL_MESSAGE
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
pbr
|
pbr
|
||||||
aprsd>=2.7.0
|
aprsd>=3.0.0
|
||||||
tweepy
|
tweepy
|
||||||
|
oslo-config
|
||||||
|
@ -19,6 +19,10 @@ description_file =
|
|||||||
README.rst
|
README.rst
|
||||||
summary = Python APRSD plugin to send tweets
|
summary = Python APRSD plugin to send tweets
|
||||||
|
|
||||||
|
[options.entry_points]
|
||||||
|
oslo.config.opts =
|
||||||
|
aprsd_twitter_plugin.conf = aprsd_twitter_plugin.conf.opts:list_opts
|
||||||
|
|
||||||
[global]
|
[global]
|
||||||
setup-hooks =
|
setup-hooks =
|
||||||
pbr.hooks.setup_hook
|
pbr.hooks.setup_hook
|
||||||
|
Loading…
Reference in New Issue
Block a user