mirror of https://gitlab.com/chaica/feed2toot
Merge branch 'add-feedname' into 'master'
Add the ability to use {feedname} in the tweet template See merge request !7
This commit is contained in:
commit
67b7e72507
|
@ -5,7 +5,7 @@ As a prerequisite to use Feed2toot, you need to authorize a Mastodon app for you
|
||||||
|
|
||||||
Just use the script register_feed2toot_app to register the feed2toot app for your account.::
|
Just use the script register_feed2toot_app to register the feed2toot app for your account.::
|
||||||
|
|
||||||
$ ./register_feed2toot_app
|
$ ./register_feed2toot_app
|
||||||
|
|
||||||
This app generates Mastodon app credentials needed by Feed2toot.
|
This app generates Mastodon app credentials needed by Feed2toot.
|
||||||
feed2toot_clientcred.txt and feed2toot_usercred.txt will be written in the current dir /home/chaica/progra/python/feed2toot.
|
feed2toot_clientcred.txt and feed2toot_usercred.txt will be written in the current dir /home/chaica/progra/python/feed2toot.
|
||||||
|
@ -107,6 +107,15 @@ Now let's have a look at the =/home/john/feed2toot/rsslist.txt file::
|
||||||
|
|
||||||
Each line of this file is a url to a rss feed. Pretty simple.
|
Each line of this file is a url to a rss feed. Pretty simple.
|
||||||
|
|
||||||
|
Display the name of the feed in the toots
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
If you want to display the name of the feed in the resulting toot, you can do so by giving it a name with the following syntax::
|
||||||
|
|
||||||
|
Le journal du hacker <https://www.journalduhacker.net/rss/>
|
||||||
|
|
||||||
|
Then in the `tweet` configuration, you can use the `{feedname}` syntax, which will be replaced by the actual name of the feed.
|
||||||
|
|
||||||
Match specific patterns of rss feeds in the uri_list files
|
Match specific patterns of rss feeds in the uri_list files
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
You can use specific pattern matching for uri in the uri_list file to filter some of the rss entries of a rss feed. Lets modify the previous file::
|
You can use specific pattern matching for uri in the uri_list file to filter some of the rss entries of a rss feed. Lets modify the previous file::
|
||||||
|
|
|
@ -23,6 +23,7 @@ import os
|
||||||
import os.path
|
import os.path
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
# 3rd party library imports
|
# 3rd party library imports
|
||||||
import feedparser
|
import feedparser
|
||||||
|
@ -53,9 +54,9 @@ class ConfParse(object):
|
||||||
self.accept_bozo_exceptions = False
|
self.accept_bozo_exceptions = False
|
||||||
|
|
||||||
###########################
|
###########################
|
||||||
#
|
#
|
||||||
# the rss section
|
# the rss section
|
||||||
#
|
#
|
||||||
###########################
|
###########################
|
||||||
section = 'rss'
|
section = 'rss'
|
||||||
if config.has_section(section):
|
if config.has_section(section):
|
||||||
|
@ -108,6 +109,12 @@ class ConfParse(object):
|
||||||
for line in rsslist:
|
for line in rsslist:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
# split each line in two parts, rss link and a string with the different patterns to look for
|
# split each line in two parts, rss link and a string with the different patterns to look for
|
||||||
|
feedname = None
|
||||||
|
if '<' in line:
|
||||||
|
matches = re.match('(.*) <(.*)>', line)
|
||||||
|
if not matches:
|
||||||
|
sys.exit('This line in the list of uri to parse is not formatted correctly: {line}'.format(line))
|
||||||
|
feedname, line = matches.groups()
|
||||||
confobjects = line.split('|')
|
confobjects = line.split('|')
|
||||||
if len(confobjects) > 3 or len(confobjects) == 2:
|
if len(confobjects) > 3 or len(confobjects) == 2:
|
||||||
sys.exit('This line in the list of uri to parse is not formatted correctly: {line}'.format(line))
|
sys.exit('This line in the list of uri to parse is not formatted correctly: {line}'.format(line))
|
||||||
|
@ -132,7 +139,7 @@ class ConfParse(object):
|
||||||
sys.exit('The rss object {rssobject} could not be found in the feed {rss}'.format(rssobject=rssobject, rss=rss))
|
sys.exit('The rss object {rssobject} could not be found in the feed {rss}'.format(rssobject=rssobject, rss=rss))
|
||||||
else:
|
else:
|
||||||
sys.exit('The rss feed {rss} does not seem to be valid'.format(rss=rss))
|
sys.exit('The rss feed {rss} does not seem to be valid'.format(rss=rss))
|
||||||
feeds.append({'feed': feed, 'patterns': patterns, 'rssobject': rssobject})
|
feeds.append({'feed': feed, 'patterns': patterns, 'rssobject': rssobject, 'feedname': feedname})
|
||||||
# test if all feeds in the list were unsuccessfully retrieved and if so, leave
|
# test if all feeds in the list were unsuccessfully retrieved and if so, leave
|
||||||
if not feeds and bozoexception:
|
if not feeds and bozoexception:
|
||||||
sys.exit('No feed could be retrieved. Leaving.')
|
sys.exit('No feed could be retrieved. Leaving.')
|
||||||
|
@ -161,9 +168,9 @@ class ConfParse(object):
|
||||||
if config.has_option(section, currentoption):
|
if config.has_option(section, currentoption):
|
||||||
options['nopatternurinoglobalpattern'] = config.getboolean(section, currentoption)
|
options['nopatternurinoglobalpattern'] = config.getboolean(section, currentoption)
|
||||||
###########################
|
###########################
|
||||||
#
|
#
|
||||||
# the cache section
|
# the cache section
|
||||||
#
|
#
|
||||||
###########################
|
###########################
|
||||||
section = 'cache'
|
section = 'cache'
|
||||||
if not self.clioptions.cachefile:
|
if not self.clioptions.cachefile:
|
||||||
|
@ -191,9 +198,9 @@ class ConfParse(object):
|
||||||
else:
|
else:
|
||||||
options['cache_limit'] = 100
|
options['cache_limit'] = 100
|
||||||
###########################
|
###########################
|
||||||
#
|
#
|
||||||
# the hashtag section
|
# the hashtag section
|
||||||
#
|
#
|
||||||
###########################
|
###########################
|
||||||
section = 'hashtaglist'
|
section = 'hashtaglist'
|
||||||
if not self.clioptions.hashtaglist:
|
if not self.clioptions.hashtaglist:
|
||||||
|
@ -207,9 +214,9 @@ class ConfParse(object):
|
||||||
else:
|
else:
|
||||||
options['hashtaglist'] = ''
|
options['hashtaglist'] = ''
|
||||||
###########################
|
###########################
|
||||||
#
|
#
|
||||||
# the plugins section
|
# the plugins section
|
||||||
#
|
#
|
||||||
###########################
|
###########################
|
||||||
plugins = {}
|
plugins = {}
|
||||||
section = 'influxdb'
|
section = 'influxdb'
|
||||||
|
@ -236,7 +243,7 @@ class ConfParse(object):
|
||||||
self.confs.append((options, config, self.tweetformat, feeds, plugins))
|
self.confs.append((options, config, self.tweetformat, feeds, plugins))
|
||||||
else:
|
else:
|
||||||
self.confs.append((options, config, self.tweetformat, [{'feed': feed, 'patterns': [], 'rssobject': ''}], plugins))
|
self.confs.append((options, config, self.tweetformat, [{'feed': feed, 'patterns': [], 'rssobject': ''}], plugins))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def confvalues(self):
|
def confvalues(self):
|
||||||
'''Return the values of the different configuration files'''
|
'''Return the values of the different configuration files'''
|
||||||
|
|
|
@ -27,7 +27,7 @@ import feedparser
|
||||||
|
|
||||||
class FilterEntry(object):
|
class FilterEntry(object):
|
||||||
'''FilterEntry class'''
|
'''FilterEntry class'''
|
||||||
def __init__(self, elements, entry, options, byrsspatterns, rssobject):
|
def __init__(self, elements, entry, options, byrsspatterns, rssobject, feedname):
|
||||||
'''Constructor of the FilterEntry class'''
|
'''Constructor of the FilterEntry class'''
|
||||||
self.matching = {}
|
self.matching = {}
|
||||||
self.entry = entry
|
self.entry = entry
|
||||||
|
@ -35,15 +35,20 @@ class FilterEntry(object):
|
||||||
self.options = options
|
self.options = options
|
||||||
self.byrsspatterns = byrsspatterns
|
self.byrsspatterns = byrsspatterns
|
||||||
self.rssobject = rssobject
|
self.rssobject = rssobject
|
||||||
|
self.feedname = feedname
|
||||||
self.main()
|
self.main()
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
'''Main of the FilterEntry class'''
|
'''Main of the FilterEntry class'''
|
||||||
|
authorized_elements = ['feedname', ]
|
||||||
|
authorized_elements.extend(self.entry.keys())
|
||||||
for i in self.elements:
|
for i in self.elements:
|
||||||
if i not in self.entry:
|
if i not in authorized_elements:
|
||||||
sys.exit('The element {} is not available in the RSS feed. The available ones are: {}'.format(i, [j for j in self.entry]))
|
sys.exit('The element {} is not available in the RSS feed. The available ones are: {}'.format(i, [j for j in self.entry]))
|
||||||
# for the case if no pattern at all is defined
|
# for the case if no pattern at all is defined
|
||||||
if not self.options['patterns'] and not self.byrsspatterns and not self.rssobject:
|
if i == 'feedname':
|
||||||
|
self.matching[i] = self.feedname
|
||||||
|
elif not self.options['patterns'] and not self.byrsspatterns and not self.rssobject:
|
||||||
self.matching[i] = self.entry[i]
|
self.matching[i] = self.entry[i]
|
||||||
# global filter only
|
# global filter only
|
||||||
elif self.options['patterns'] and not self.byrsspatterns and not self.rssobject:
|
elif self.options['patterns'] and not self.byrsspatterns and not self.rssobject:
|
||||||
|
@ -67,7 +72,7 @@ class FilterEntry(object):
|
||||||
if not self.options['patternscasesensitive']['{}_case_sensitive'.format(patternlist)]:
|
if not self.options['patternscasesensitive']['{}_case_sensitive'.format(patternlist)]:
|
||||||
# not case sensitive, so we compare the lower case
|
# not case sensitive, so we compare the lower case
|
||||||
for pattern in self.options['patterns'][patternlist]:
|
for pattern in self.options['patterns'][patternlist]:
|
||||||
finalpattern = pattern.lower()
|
finalpattern = pattern.lower()
|
||||||
finaltitle = self.entry[patternlist.split('_')[0]].lower()
|
finaltitle = self.entry[patternlist.split('_')[0]].lower()
|
||||||
if finalpattern in finaltitle:
|
if finalpattern in finaltitle:
|
||||||
self.matching[i] = self.entry[i]
|
self.matching[i] = self.entry[i]
|
||||||
|
|
|
@ -173,7 +173,7 @@ class Main(object):
|
||||||
tmpelement = i.strip('{}')
|
tmpelement = i.strip('{}')
|
||||||
elements.append(tmpelement)
|
elements.append(tmpelement)
|
||||||
# match elements of the tweet format string with available element in the RSS feed
|
# match elements of the tweet format string with available element in the RSS feed
|
||||||
fe = FilterEntry(elements, entry, options, feed['patterns'], feed['rssobject'])
|
fe = FilterEntry(elements, entry, options, feed['patterns'], feed['rssobject'], feed['feedname'])
|
||||||
entrytosend = fe.finalentry
|
entrytosend = fe.finalentry
|
||||||
if entrytosend:
|
if entrytosend:
|
||||||
tweetwithnotag = tweetformat.format(**entrytosend)
|
tweetwithnotag = tweetformat.format(**entrytosend)
|
||||||
|
@ -186,7 +186,7 @@ class Main(object):
|
||||||
finaltweet = addtag.finaltweet
|
finaltweet = addtag.finaltweet
|
||||||
else:
|
else:
|
||||||
finaltweet = dedup.finaltweet
|
finaltweet = dedup.finaltweet
|
||||||
|
|
||||||
if clioptions.dryrun:
|
if clioptions.dryrun:
|
||||||
if entrytosend:
|
if entrytosend:
|
||||||
logging.warning('Would toot with visibility "{visibility}": {toot}'.format(
|
logging.warning('Would toot with visibility "{visibility}": {toot}'.format(
|
||||||
|
@ -219,7 +219,7 @@ class Main(object):
|
||||||
pluginmodulename = 'feed2toot.plugins.{pluginmodule}'.format(pluginmodule=pluginclassname.lower())
|
pluginmodulename = 'feed2toot.plugins.{pluginmodule}'.format(pluginmodule=pluginclassname.lower())
|
||||||
try:
|
try:
|
||||||
pluginmodule = importlib.import_module(pluginmodulename)
|
pluginmodule = importlib.import_module(pluginmodulename)
|
||||||
pluginclass = getattr(pluginmodule, pluginclassname)
|
pluginclass = getattr(pluginmodule, pluginclassname)
|
||||||
pluginclass(plugins[plugin], finaltweet)
|
pluginclass(plugins[plugin], finaltweet)
|
||||||
except ImportError as err:
|
except ImportError as err:
|
||||||
print(err)
|
print(err)
|
||||||
|
|
Loading…
Reference in New Issue