Skip to content

Commit

Permalink
WIP towards yml configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
NNTin committed Mar 10, 2019
1 parent e7d3fde commit 450d1bb
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,5 @@ $RECYCLE.BIN/
*.xml
.idea/discord-twitter-bot.iml
experiment/
bot/config.json
bot/config.json
bot/.env
83 changes: 83 additions & 0 deletions bot/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
######################################
#### manual configuration example: ###
#Twitter:
# access_token: XXX-XXX
# access_token_secret: XXX
# consumer_key: XXX
# consumer_secret: XXX
#
#Discord:
# - IncludeReplyToUser: false
# IncludeRetweet: false
# IncludeUserReply: true
# custom_message: 'A new tweet!'
# keyword_sets:
# - - 'League' # tweet will be posted if tweet contains all 3 words (League of Legends), no particular order.
# - 'of'
# - 'Legends'
# - - 'Dota 2' # tweet will be posted if tweet contains 'Dota 2' in this specific order
# - - 'MOBA' # tweet will be posted if it contains 'MOBA'
# twitter_ids:
# - '123' # define as many as you want with a dash (-) at the beginning
# - '456'
# twitter_handles:
# - 'discordapp'
# twitter_lists:
# - 'https://twitter.com/rokxx/lists/dota-2'
# webhook_urls:
# - 'https://discordapp.com/api/webhooks/123456/XXXX-XXXX'
######################################

# configuration through environment variables
Twitter:
access_token: ${ACCESS_TOKEN}
access_token_secret: ${ACCESS_TOKEN_SECRET}
consumer_key: ${CONSUMER_KEY}
consumer_secret: ${CONSUMER_SECRET}

Discord:
- IncludeReplyToUser: ${INCLUDE_REPLY_TO_USER}
IncludeRetweet: ${INCLUDE_RETWEET}
IncludeUserReply: ${INCLUDE_USER_REPLY}
custom_message: ${CUSTOM_MESSAGE}
keyword_sets: ${KEYWORDS}
twitter_ids: ${TWITTER_ID}
twitter_handles: ${TWITTER_HANDLE}
twitter_lists: ${TWITTER_LIST}
webhook_urls: ${WEBHOOK_URL}
- IncludeReplyToUser: ${INCLUDE_REPLY_TO_USER_2}
IncludeRetweet: ${INCLUDE_RETWEET_2}
IncludeUserReply: ${INCLUDE_USER_REPLY_2}
custom_message: ${CUSTOM_MESSAGE_2}
keyword_sets: ${KEYWORDS_2}
twitter_ids: ${TWITTER_ID_2}
twitter_handles: ${TWITTER_HANDLE_2}
twitter_lists: ${TWITTER_LIST_2}
webhook_urls: ${WEBHOOK_URL_2}
- IncludeReplyToUser: ${INCLUDE_REPLY_TO_USER_3}
IncludeRetweet: ${INCLUDE_RETWEET_3}
IncludeUserReply: ${INCLUDE_USER_REPLY_3}
custom_message: ${CUSTOM_MESSAGE_3}
keyword_sets: ${KEYWORDS_3}
twitter_ids: ${TWITTER_ID_3}
twitter_handles: ${TWITTER_HANDLE_3}
twitter_lists: ${TWITTER_LIST_3}
webhook_urls: ${WEBHOOK_URL_3}
- IncludeReplyToUser: ${INCLUDE_REPLY_TO_USER_4}
IncludeRetweet: ${INCLUDE_RETWEET_4}
IncludeUserReply: ${INCLUDE_USER_REPLY_4}
custom_message: ${CUSTOM_MESSAGE_4}
keyword_sets: ${KEYWORDS_4}
twitter_ids: ${TWITTER_ID_4}
twitter_handles: ${TWITTER_HANDLE_4}
twitter_lists: ${TWITTER_LIST_4}
webhook_urls: ${WEBHOOK_URL_4}
- IncludeReplyToUser: ${INCLUDE_REPLY_TO_USER_5}
IncludeRetweet: ${INCLUDE_RETWEET_5}
IncludeUserReply: ${INCLUDE_USER_REPLY_5}
custom_message: ${CUSTOM_MESSAGE_5}
keyword_sets: ${KEYWORDS_5}
twitter_ids: ${TWITTER_ID_5}
twitter_handles: ${TWITTER_HANDLE_5}
twitter_lists: ${TWITTER_LIST_5}
webhook_urls: ${WEBHOOK_URL_5}
66 changes: 66 additions & 0 deletions bot/yml_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from tweepy import OAuthHandler
from dotenv import load_dotenv
import yaml
import os
import re


class CustomFormatter():
FALSE_STRINGS = ["false", "False", "f", "F", "0", "", "n", "N", "no", "No", "NO", "FALSE"]

def to_bool(self, value: str) -> bool:
return False if value in self.FALSE_STRINGS else True

def format(self, value):
return self.convert_field(*value.split("!"))

def convert_field(self, value, conversion: str):
if isinstance(value, str):
if conversion == 's': # string is alrdy a string
return value
elif conversion == 'b': # turn string into a bool()
return self.to_bool(value)
elif conversion == 'l': # turn string into a list()
return value.split(',')
elif conversion == 'll': # turn string into a double list()
return [v.split('+') for v in value.split(',')]
else:
raise ValueError("Unknown conversion specifier {0!s}".format(conversion))
else:
return None


CONFIG_YAML = os.path.abspath(os.path.join(os.path.dirname(__file__), "config.yml"))
DOTENV_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".env"))

load_dotenv(dotenv_path=DOTENV_PATH)
config = dict()

path_matcher = re.compile(r'\$\{([^}^{]+)\}')


def path_constructor(loader, node):
value = node.value
match = path_matcher.match(value)
env_var = match.group()[2:-1]
return os.environ.get(env_var, None) # + value[match.end():]

yaml.add_implicit_resolver('!path', path_matcher)
yaml.add_constructor('!path', path_constructor)

with open(CONFIG_YAML, 'r') as stream:
try:
config = yaml.load(stream)
except yaml.YAMLError as exc:
print(exc)


config['Discord'] = [{k: v for k, v in instance.items() if v is not None} for instance in config['Discord']]


auth = OAuthHandler(config["Twitter"]["consumer_key"], config["Twitter"]["consumer_secret"])
auth.set_access_token(config["Twitter"]["access_token"], config["Twitter"]["access_token_secret"])

if __name__ == '__main__':
print(config)
print(os.environ.get("CONSUMER_KEY", None))
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ idna-ssl==1.1.0
multidict==4.5.2
oauthlib==3.0.1
PySocks==1.6.8
python-dotenv==0.10.1
PyYAML==3.13
requests==2.21.0
requests-oauthlib==1.2.0
six==1.12.0
Expand Down

0 comments on commit 450d1bb

Please sign in to comment.