Merge branch '45' to solve bug #45 about sending multiple times the same message to Mastodon

This commit is contained in:
Carl Chenet 2019-08-22 00:26:32 +02:00
commit 64f33ecfac
5 changed files with 127 additions and 0 deletions

View file

@ -52,8 +52,14 @@ class CliParse:
help='tweet all RSS items, regardless of cache')
parser.add_argument('-l', '--limit', dest='limit', default=10, type=int,
help='tweet only LIMIT items (default: %(default)s)')
parser.add_argument('-t', '--lock-timeout', dest='locktimeout', default=3600, type=int,
help='lock timeout in seconds after which feed2toot can removes the lock itself')
parser.add_argument('--cachefile', dest='cachefile',
help='location of the cache file (default: %(default)s)')
parser.add_argument('--lockfile', dest='lockfile',
default=os.path.join(os.getenv('XDG_CONFIG_HOME', '~/.config'),
'feed2toot.lock'),
help='location of the lock file (default: %(default)s)')
parser.add_argument('-n', '--dry-run', dest='dryrun',
action='store_true', default=False,
help='Do not actually post tweets')

View file

@ -31,6 +31,7 @@ import feedparser
from feed2toot.confparsers.cache import parsecache
from feed2toot.confparsers.hashtaglist import parsehashtaglist
from feed2toot.confparsers.feedparser import parsefeedparser
from feed2toot.confparsers.lock import parselock
from feed2toot.confparsers.media import parsemedia
from feed2toot.confparsers.plugins import parseplugins
from feed2toot.confparsers.rss.pattern import parsepattern
@ -69,6 +70,10 @@ class ConfParse:
# pattern and patter_case_sensitive format option
#################################################
options['patterns'], options['patternscasesensitive'] = parsepattern(config)
#################################################
# lock file options
#################################################
options['lockfile'], options['locktimeout'] = parselock(self.clioptions.lockfile, self.clioptions.locktimeout, config)
###############################
# addtags option, default: True
###############################

View file

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
# Copyright © 2015-2019 Carl Chenet <carl.chenet@ohmytux.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/
# Get values of the lock section
'''Get values of the lock section'''
# standard library imports
import os.path
import sys
def parselock(lockfile, locktimeout, config):
'''Parse configuration values and get values of the hashtaglist section'''
lockfile = lockfile
locktimeout = locktimeout
section = 'lock'
##################
# lockfile option
##################
confoption = 'lock_file'
if config.has_section(section):
lockfile = config.get(section, confoption)
lockfile = os.path.expanduser(lockfile)
lockfileparent = os.path.dirname(lockfile)
if lockfileparent and not os.path.exists(lockfileparent):
sys.exit('The parent directory of the cache file does not exist: {lockfileparent}'.format(lockfileparent=lockfileparent))
######################
# lock_timeout option
######################
if config.has_section(section):
confoption = 'lock_timeout'
if config.has_option(section, confoption):
try:
locktimeout = int(config.get(section, confoption))
except ValueError as err:
sys.exit('Error in configuration with the {confoption} parameter in [{section}]: {err}'.format(confoption=confoption, section=section, err=err))
return lockfile, locktimeout

63
feed2toot/lock.py Normal file
View file

@ -0,0 +1,63 @@
# vim:ts=4:sw=4:ft=python:fileencoding=utf-8
# Copyright © 2015-2019 Carl Chenet <carl.chenet@ohmytux.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
'''Manage a lock file'''
# standard libraires imports
import datetime
import logging
import os
import os.path
import sys
class LockFile:
'''LockFile object'''
def __init__(self, lockfile, locktimeout):
'''check the lockfile and the locktimeout'''
self.lockfile = lockfile
ltimeout = datetime.timedelta(seconds=locktimeout)
self.lfdateformat = '%Y-%m-%d_%H-%M-%S'
# if a lock file exists
if os.path.exists(self.lockfile):
if os.path.isfile(self.lockfile):
with open(self.lockfile, 'r') as lf:
lfcontent = lf.read().rstrip()
# lfcontent should be a datetime
logging.debug('Check if lock file is older than timeout ({timeout} secs)'.format(timeout=locktimeout))
locktime = datetime.datetime.strptime(lfcontent, self.lfdateformat)
if locktime < (datetime.datetime.now() - ltimeout):
# remove the lock file
logging.debug('Found an expired lock file')
self.release()
self.create_lock()
else:
# quit because another feed2toot process is running
logging.debug('Found a valid lock file. Exiting immediately.')
sys.exit(0)
else:
# no lock file. Creating one
self.create_lock()
def create_lock(self):
'''Create a lock file'''
with open(self.lockfile, 'w') as lf:
currentdatestring = datetime.datetime.now().strftime(self.lfdateformat)
lf.write(currentdatestring)
logging.debug('lockfile {lockfile} created.'.format(lockfile=self.lockfile))
def release(self):
'''Release the lockfile'''
os.remove(self.lockfile)
logging.debug('Removed lock file.')

View file

@ -32,6 +32,7 @@ from feed2toot.filterentry import FilterEntry
from feed2toot.removeduplicates import RemoveDuplicates
from feed2toot.tootpost import TootPost
from feed2toot.feedcache import FeedCache
from feed2toot.lock import LockFile
from bs4 import BeautifulSoup
class Main:
@ -71,6 +72,8 @@ class Main:
tweetformat = conf[2]
feeds = conf[3]
plugins = conf[4]
# check the logfile and logtimeout
lockfile = LockFile(options['lockfile'], options['locktimeout'])
# create link to the persistent list
cache = FeedCache(options)
if 'hashtaglist' in options and options['hashtaglist']:
@ -221,3 +224,5 @@ class Main:
print(err)
# do not forget to close cache (shelf object)
cache.close()
# release the lock file
lockfile.release()