|
|
@ -3,7 +3,7 @@ |
|
|
|
# |
|
|
|
# redfam.py |
|
|
|
# |
|
|
|
# Copyright 2015 GOLDERWEB – Jonathan Golder <jonathan@golderweb.de> |
|
|
|
# Copyright 2017 GOLDERWEB – Jonathan Golder <jonathan@golderweb.de> |
|
|
|
# |
|
|
|
# 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 |
|
|
@ -35,10 +35,10 @@ import pywikibot # noqa |
|
|
|
from pywikibot.tools import deprecated # noqa |
|
|
|
|
|
|
|
import jogobot |
|
|
|
from lib.mysqlred import MysqlRedFam |
|
|
|
from lib.mysqlred import MysqlRedFam, text |
|
|
|
|
|
|
|
|
|
|
|
class RedFam: |
|
|
|
class RedFam( MysqlRedFam ): |
|
|
|
""" |
|
|
|
Basic class for RedFams, containing the basic data structure |
|
|
|
""" |
|
|
@ -60,22 +60,16 @@ class RedFam: |
|
|
|
# Having pywikibot.Site() is a good idea most of the time |
|
|
|
self.site = pywikibot.Site() |
|
|
|
|
|
|
|
# Database interface |
|
|
|
self._mysql = MysqlRedFam( famhash ) |
|
|
|
|
|
|
|
# Initial attribute values |
|
|
|
self._articlesList = articlesList |
|
|
|
self._beginning = beginning |
|
|
|
self._ending = ending |
|
|
|
self._redpageid = redpageid |
|
|
|
self._status = set() |
|
|
|
self._status = self._parse_status(status) |
|
|
|
self._famhash = famhash |
|
|
|
self._heading = heading |
|
|
|
|
|
|
|
# Calculates the sha1 hash over self._articlesList to |
|
|
|
# rediscover known redundance families |
|
|
|
self.calc_famhash() |
|
|
|
super().__init__( |
|
|
|
articlesList=articlesList, |
|
|
|
beginning=beginning, |
|
|
|
ending=ending, |
|
|
|
redpageid=redpageid, |
|
|
|
famhash=famhash, |
|
|
|
heading=heading, |
|
|
|
status=status, |
|
|
|
articlesStatus=None |
|
|
|
) |
|
|
|
|
|
|
|
def __repr__( self ): |
|
|
|
""" |
|
|
@ -85,18 +79,20 @@ class RedFam: |
|
|
|
""" |
|
|
|
|
|
|
|
__repr = "RedFam( " + \ |
|
|
|
"articlesList=" + repr( self._articlesList ) + \ |
|
|
|
", heading=" + repr( self._heading ) + \ |
|
|
|
", beginning=" + repr( self._beginning ) + \ |
|
|
|
", ending=" + repr( self._ending ) + \ |
|
|
|
", red_page_id=" + repr( self._redpageid ) + \ |
|
|
|
", status=" + repr( self._status ) + \ |
|
|
|
", fam_hash=" + repr( self._famhash ) + \ |
|
|
|
"articlesList=" + repr( self.articlesList ) + \ |
|
|
|
", heading=" + repr( self.heading ) + \ |
|
|
|
", beginning=" + repr( self.beginning ) + \ |
|
|
|
", ending=" + repr( self.ending ) + \ |
|
|
|
", red_page_id=" + repr( self.redpageid ) + \ |
|
|
|
", status=" + repr( self.status ) + \ |
|
|
|
", fam_hash=" + repr( self.famhash ) + \ |
|
|
|
", articlesStatus=" + repr( self.articlesStatus ) + \ |
|
|
|
" )" |
|
|
|
|
|
|
|
return __repr |
|
|
|
|
|
|
|
def calc_famhash( self ): |
|
|
|
@classmethod |
|
|
|
def calc_famhash(cls, articlesList ): |
|
|
|
""" |
|
|
|
Calculates the SHA-1 hash for the articlesList of redundance family. |
|
|
|
Since we don't need security SHA-1 is just fine. |
|
|
@ -105,99 +101,21 @@ class RedFam: |
|
|
|
""" |
|
|
|
|
|
|
|
h = hashlib.sha1() |
|
|
|
h.update( str( self._articlesList[:8] ).encode('utf-8') ) |
|
|
|
# Since articlesList attr of RedFam will have always 8 Members we |
|
|
|
# need to fill up smaller lists (longers will be cropped below). |
|
|
|
while len( articlesList) < 8: |
|
|
|
articlesList.append(None) |
|
|
|
|
|
|
|
if self._famhash and h.hexdigest() != self._famhash: |
|
|
|
raise RedFamHashError( self._famhash, h.hexdigest() ) |
|
|
|
h.update( str( articlesList[:8] ).encode('utf-8') ) |
|
|
|
|
|
|
|
elif self._famhash: |
|
|
|
return |
|
|
|
else: |
|
|
|
self._famhash = h.hexdigest() |
|
|
|
|
|
|
|
def changed( self ): |
|
|
|
""" |
|
|
|
Checks wether anything has changed and maybe triggers db update |
|
|
|
""" |
|
|
|
|
|
|
|
# On archived redfams do not delete possibly existing ending |
|
|
|
if( not self._ending and "archived" in self._status and |
|
|
|
self._mysql.data[ 'ending' ] ): |
|
|
|
|
|
|
|
self._ending = self._mysql.data[ 'ending' ] |
|
|
|
|
|
|
|
# Since status change means something has changed, update database |
|
|
|
if( self._raw_status != self._mysql.data[ 'status' ] or |
|
|
|
self._beginning != self._mysql.data[ 'beginning' ] or |
|
|
|
self._ending != self._mysql.data[ 'ending' ] or |
|
|
|
self._red_page_id != self._mysql.data[ 'redpageid' ] or |
|
|
|
self._heading != self._mysql.data[ 'heading' ]): |
|
|
|
|
|
|
|
self._mysql.update_fam( self._redpageid, self._heading, |
|
|
|
self._beginning, self._ending, |
|
|
|
self._raw_status() ) |
|
|
|
return h.hexdigest() |
|
|
|
|
|
|
|
@classmethod |
|
|
|
def flush_db_cache( cls ): |
|
|
|
""" |
|
|
|
Calls flush method of Mysql Interface class |
|
|
|
""" |
|
|
|
MysqlRedFam.flush() |
|
|
|
|
|
|
|
def add_status(self, status): |
|
|
|
""" |
|
|
|
Adds a status specified by status, to status set |
|
|
|
|
|
|
|
@param status Statusstring to add |
|
|
|
@type status str |
|
|
|
""" |
|
|
|
self._status.add(status) |
|
|
|
|
|
|
|
def remove_status(self, status, weak=True): |
|
|
|
""" |
|
|
|
Removes a status, specified by status from set. If weak is set to |
|
|
|
False it will throw a KeyError when trying to remove a status not set. |
|
|
|
|
|
|
|
@param status Statusstring to add |
|
|
|
@type status str |
|
|
|
@param weak Change behavior on missing status |
|
|
|
@type bool |
|
|
|
""" |
|
|
|
if weak: |
|
|
|
self._status.discard(status) |
|
|
|
else: |
|
|
|
self._status.remove(status) |
|
|
|
|
|
|
|
def has_status(self, status): |
|
|
|
""" |
|
|
|
Returns True, if redfam has given status |
|
|
|
|
|
|
|
@param status Statusstring to check |
|
|
|
@type status str |
|
|
|
@returns True if status is present else False |
|
|
|
""" |
|
|
|
if status in self._status: |
|
|
|
return True |
|
|
|
else: |
|
|
|
return False |
|
|
|
|
|
|
|
def _parse_status(self, raw_status ): |
|
|
|
""" |
|
|
|
Sets status based on comma separated list |
|
|
|
|
|
|
|
@param raw_status Commaseparated string of stati (from DB) |
|
|
|
@type raw_status str |
|
|
|
""" |
|
|
|
self._status = set( raw_status.strip().split(",")) |
|
|
|
|
|
|
|
def _raw_status( self ): |
|
|
|
""" |
|
|
|
Returns status as commaseparated string (to save in DB) |
|
|
|
|
|
|
|
@returns Raw status string |
|
|
|
@rtype str |
|
|
|
""" |
|
|
|
return ",".join( self._status ) |
|
|
|
cls.session.commit() |
|
|
|
|
|
|
|
def article_add_status(self, status, index=None, title=None ): |
|
|
|
""" |
|
|
@ -212,10 +130,10 @@ class RedFam: |
|
|
|
@type title str |
|
|
|
""" |
|
|
|
if title and not index: |
|
|
|
index = self._articlesList.index( title ) |
|
|
|
index = self.articlesList.index( title ) |
|
|
|
|
|
|
|
if isinstance( index, int ) and index < len(self._articlesList): |
|
|
|
self._article_status[index].add(status) |
|
|
|
if isinstance( index, int ) and index < len(self.articlesList): |
|
|
|
self.articlesStatus[index].add(status) |
|
|
|
else: |
|
|
|
raise IndexError( "No index given or wrong format!") |
|
|
|
|
|
|
@ -236,13 +154,13 @@ class RedFam: |
|
|
|
@type bool |
|
|
|
""" |
|
|
|
if title and not index: |
|
|
|
index = self._articlesList.index( title ) |
|
|
|
index = self.articlesList.index( title ) |
|
|
|
|
|
|
|
if isinstance( index, int ) and index < len(self._articlesList): |
|
|
|
if isinstance( index, int ) and index < len(self.articlesList): |
|
|
|
if weak: |
|
|
|
self._article_status[index].discard(status) |
|
|
|
self.articlesStatus[index].discard(status) |
|
|
|
else: |
|
|
|
self._article_status[index].remove(status) |
|
|
|
self.articlesStatus[index].remove(status) |
|
|
|
else: |
|
|
|
raise IndexError( "No index given or wrong format!") |
|
|
|
|
|
|
@ -259,56 +177,16 @@ class RedFam: |
|
|
|
@type title str |
|
|
|
""" |
|
|
|
if title and not index: |
|
|
|
index = self._articlesList.index( title ) |
|
|
|
index = self.articlesList.index( title ) |
|
|
|
|
|
|
|
if isinstance( index, int ) and index < len(self._articlesList): |
|
|
|
if status in self._article_status[index]: |
|
|
|
if isinstance( index, int ) and index < len(self.articlesList): |
|
|
|
if status in self.articlesStatus[index]: |
|
|
|
return True |
|
|
|
else: |
|
|
|
return False |
|
|
|
else: |
|
|
|
raise IndexError( "No index given or wrong format!") |
|
|
|
|
|
|
|
def _article_parse_status(self, raw_status, index=None, title=None ): |
|
|
|
""" |
|
|
|
Sets status based on comma separated list to articles (identified by |
|
|
|
title or index in articlesList) status set |
|
|
|
|
|
|
|
@param status Statusstring to set |
|
|
|
@type status str |
|
|
|
@param index Add to article with index in articlesList |
|
|
|
@type index int |
|
|
|
@param title Add to article with title in articlesList |
|
|
|
@type title str |
|
|
|
""" |
|
|
|
if title and not index: |
|
|
|
index = self._articlesList.index( title ) |
|
|
|
|
|
|
|
if isinstance( index, int ) and index < len(self._articlesList): |
|
|
|
self._article_status[index] = set( raw_status.strip().split(",")) |
|
|
|
else: |
|
|
|
raise IndexError( "No index given or wrong format!") |
|
|
|
|
|
|
|
def _article_raw_status( self, index=None, title=None ): |
|
|
|
""" |
|
|
|
Returns status as commaseparated string (to save in DB) of article |
|
|
|
(identified by title or index in articlesList) status set |
|
|
|
|
|
|
|
@param index Get from article with index in articlesList |
|
|
|
@type index int |
|
|
|
@param title Get from article with title in articlesList |
|
|
|
@type title str |
|
|
|
@returns Raw status string |
|
|
|
@rtype str |
|
|
|
""" |
|
|
|
if title and not index: |
|
|
|
index = self._articlesList.index( title ) |
|
|
|
|
|
|
|
if isinstance( index, int ) and index < len(self._articlesList): |
|
|
|
return ",".join( self._article_status[index] ) |
|
|
|
else: |
|
|
|
raise IndexError( "No index given or wrong format!") |
|
|
|
|
|
|
|
|
|
|
|
class RedFamParser( RedFam ): |
|
|
|
""" |
|
|
@ -331,7 +209,7 @@ class RedFamParser( RedFam ): |
|
|
|
wurde gewünscht von:" |
|
|
|
__done_notice2 = "{{Erledigt|" |
|
|
|
|
|
|
|
def __init__( self, heading, redpage, redpagearchive, |
|
|
|
def __init__( self, articlesList, heading, redpage, redpagearchive, |
|
|
|
beginning, ending=None ): |
|
|
|
""" |
|
|
|
Creates a RedFam object based on data collected while parsing red_pages |
|
|
@ -346,57 +224,50 @@ class RedFamParser( RedFam ): |
|
|
|
str strptime parseable string |
|
|
|
""" |
|
|
|
|
|
|
|
# Set object attributes: |
|
|
|
self._redpageid = redpage._pageid |
|
|
|
self._redpagearchive = redpagearchive |
|
|
|
self._famhash = None |
|
|
|
|
|
|
|
# Method self.add_beginning sets self._beginning directly |
|
|
|
self.add_beginning( beginning ) |
|
|
|
# Calculates the sha1 hash over self._articlesList to |
|
|
|
# rediscover known redundance families |
|
|
|
famhash = type(self).calc_famhash(articlesList) |
|
|
|
|
|
|
|
# Method self.add_ending sets self._ending directly |
|
|
|
if( ending ): |
|
|
|
self.add_ending( ending ) |
|
|
|
else: |
|
|
|
# If no ending was provided set to None |
|
|
|
self._ending = None |
|
|
|
# Set object attributes: |
|
|
|
self.redpage = redpage |
|
|
|
|
|
|
|
self._status = set() |
|
|
|
# Parse Timestamps |
|
|
|
beginning = self.__datetime(beginning) |
|
|
|
if ending: |
|
|
|
ending = self.__datetime(ending) |
|
|
|
|
|
|
|
# Parse the provided heading of redundance section |
|
|
|
# to set self._articlesList |
|
|
|
self.heading_parser( heading ) |
|
|
|
super().__init__( articlesList, |
|
|
|
beginning, |
|
|
|
ending=ending, |
|
|
|
redpageid=redpage.page._pageid, |
|
|
|
famhash=famhash, |
|
|
|
heading=heading ) |
|
|
|
|
|
|
|
# Calculates the sha1 hash over self._articlesList to |
|
|
|
# rediscover known redundance families |
|
|
|
# Check status changes |
|
|
|
self.check_status() |
|
|
|
|
|
|
|
self.calc_famhash() |
|
|
|
self.session.add(self) |
|
|
|
|
|
|
|
# Open database connection, ask for data if existing, |
|
|
|
# otherwise create entry |
|
|
|
self.__handle_db() |
|
|
|
def update( self, articlesList, heading, redpage, redpagearchive, |
|
|
|
beginning, ending=None ): |
|
|
|
|
|
|
|
# Check status changes |
|
|
|
self.status() |
|
|
|
self.articlesList = articlesList |
|
|
|
self.heading = heading |
|
|
|
self.redpage = redpage |
|
|
|
self.redpageid = redpage.pageid |
|
|
|
|
|
|
|
# Triggers db update if anything changed |
|
|
|
self.changed() |
|
|
|
self.add_beginning( beginning ) |
|
|
|
|
|
|
|
def __handle_db( self ): |
|
|
|
""" |
|
|
|
Handles opening of db connection |
|
|
|
""" |
|
|
|
if ending: |
|
|
|
self.add_ending( ending ) |
|
|
|
|
|
|
|
# We need a connection to our mysqldb |
|
|
|
self._mysql = MysqlRedFam( ) |
|
|
|
self._mysql.get_fam( self._famhash ) |
|
|
|
self._redpagearchive = redpagearchive |
|
|
|
|
|
|
|
if not self._mysql.data: |
|
|
|
self._mysql.add_fam( self._articlesList, self._heading, |
|
|
|
self._redpageid, self._beginning, |
|
|
|
self._ending ) |
|
|
|
# Check status changes |
|
|
|
self.check_status() |
|
|
|
|
|
|
|
def heading_parser( self, heading ): |
|
|
|
@classmethod |
|
|
|
def heading_parser( cls, heading ): |
|
|
|
""" |
|
|
|
Parses given red_fam_heading string and saves articles list |
|
|
|
|
|
|
@ -404,34 +275,13 @@ class RedFamParser( RedFam ): |
|
|
|
@type heading wikicode or mwparser-parseable |
|
|
|
""" |
|
|
|
|
|
|
|
# Save heading as string |
|
|
|
self._heading = str( heading ) |
|
|
|
|
|
|
|
# Parse string heading with mwparse again everytime |
|
|
|
# In some cases the given wikicode is broken due to syntax errors |
|
|
|
# (Task FS#77) |
|
|
|
heading = mwparser.parse( self._heading ) |
|
|
|
heading = mwparser.parse( str( heading ) ) |
|
|
|
|
|
|
|
# Save destinations of wikilinks in headings |
|
|
|
self._articlesList = [ str( link.title ) for link |
|
|
|
in heading.ifilter_wikilinks() ] |
|
|
|
|
|
|
|
# Catch sections with more then 8 articles, print error |
|
|
|
if len( self._articlesList ) > 8: |
|
|
|
# For repression in output we need to know the fam hash |
|
|
|
self.calc_famhash() |
|
|
|
|
|
|
|
jogobot.output( |
|
|
|
( "\03{{lightred}}" + |
|
|
|
"Maximum number of articles in red_fam exceeded, " + |
|
|
|
"maximum number is 8, {number:d} were given \n {repress}" |
|
|
|
).format( datetime=datetime.now().strftime( |
|
|
|
"%Y-%m-%d %H:%M:%S" ), number=len( self._articlesList ), |
|
|
|
repress=repr( self ) ), |
|
|
|
"WARNING" ) |
|
|
|
|
|
|
|
# Only save the first 8 articles |
|
|
|
self._articlesList = self._articlesList[:8] |
|
|
|
return [ str( link.title ) for link in heading.ifilter_wikilinks() ] |
|
|
|
|
|
|
|
def add_beginning( self, beginning ): |
|
|
|
""" |
|
|
@ -440,7 +290,7 @@ class RedFamParser( RedFam ): |
|
|
|
@param datetime datetime Beginning date |
|
|
|
""" |
|
|
|
|
|
|
|
self._beginning = self.__datetime( beginning ) |
|
|
|
self.beginning = self.__datetime( beginning ) |
|
|
|
|
|
|
|
def add_ending( self, ending ): |
|
|
|
""" |
|
|
@ -449,7 +299,7 @@ class RedFamParser( RedFam ): |
|
|
|
@param datetime datetime Ending date |
|
|
|
""" |
|
|
|
|
|
|
|
self._ending = self.__datetime( ending ) |
|
|
|
self.ending = self.__datetime( ending ) |
|
|
|
|
|
|
|
def __datetime( self, timestamp ): |
|
|
|
""" |
|
|
@ -473,7 +323,7 @@ class RedFamParser( RedFam ): |
|
|
|
type( self ).__timestamp_format ) |
|
|
|
return result |
|
|
|
|
|
|
|
def status( self ): |
|
|
|
def check_status( self ): |
|
|
|
""" |
|
|
|
Handles detection of correct status |
|
|
|
There are three possible stati: |
|
|
@ -485,16 +335,16 @@ class RedFamParser( RedFam ): |
|
|
|
|
|
|
|
# No ending, discussion is running: |
|
|
|
# Sometimes archived discussions also have no detectable ending |
|
|
|
if not self._ending and not self._redpagearchive: |
|
|
|
self.add_status("open") |
|
|
|
if not self.ending and not self.redpage.archive: |
|
|
|
self.status.add("open") |
|
|
|
else: |
|
|
|
self.remove_status("open") |
|
|
|
if not self._redpagearchive: |
|
|
|
self.add_status("done") |
|
|
|
self.status.remove("open") |
|
|
|
if not self.redpage.archive: |
|
|
|
self.status.add("done") |
|
|
|
else: |
|
|
|
self.remove_status("done") |
|
|
|
self.remove_status("open") |
|
|
|
self.add_status("archived") |
|
|
|
self.status.remove("done") |
|
|
|
self.status.remove("open") |
|
|
|
self.status.add("archived") |
|
|
|
|
|
|
|
@classmethod |
|
|
|
def is_section_redfam_cb( cls, heading ): |
|
|
@ -513,7 +363,7 @@ class RedFamParser( RedFam ): |
|
|
|
return False |
|
|
|
|
|
|
|
@classmethod |
|
|
|
def parser( cls, text, page, isarchive=False ): |
|
|
|
def parser( cls, text, redpage, isarchive=False ): |
|
|
|
""" |
|
|
|
Handles parsing of redfam section |
|
|
|
|
|
|
@ -526,7 +376,7 @@ class RedFamParser( RedFam ): |
|
|
|
text = mwparser.parse( text ) |
|
|
|
|
|
|
|
# Extract heading text |
|
|
|
heading = next( text.ifilter_headings() ).title |
|
|
|
heading = next( text.ifilter_headings() ).title.strip() |
|
|
|
|
|
|
|
# Extract beginnig and maybe ending |
|
|
|
(beginning, ending) = RedFamParser.extract_dates( text, isarchive ) |
|
|
@ -536,16 +386,37 @@ class RedFamParser( RedFam ): |
|
|
|
if not beginning: |
|
|
|
match = re.search( |
|
|
|
jogobot.config["redundances"]["reddiscs_onlyinclude_re"], |
|
|
|
page.title() ) |
|
|
|
redpage.page.title() ) |
|
|
|
|
|
|
|
if match: |
|
|
|
beginning = datetime.strptime( |
|
|
|
"01. {month} {year}".format( |
|
|
|
month=match.group(1), year=match.group(2)), |
|
|
|
"%d. %B %Y" ) |
|
|
|
articlesList = RedFamParser.heading_parser( heading ) |
|
|
|
famhash = RedFamParser.calc_famhash( articlesList ) |
|
|
|
|
|
|
|
# Check for existing objects in DB first in current redpage |
|
|
|
redfam = redpage.redfams.get(famhash) |
|
|
|
|
|
|
|
# Create the RedFam object |
|
|
|
RedFamParser( heading, page, isarchive, beginning, ending ) |
|
|
|
with RedFamParser.session.no_autoflush: |
|
|
|
if not redfam: |
|
|
|
# Otherwise in db table |
|
|
|
redfam = RedFamParser.session.query(RedFamParser).filter( |
|
|
|
RedFamParser.famhash == famhash ).one_or_none() |
|
|
|
|
|
|
|
if redfam: |
|
|
|
# Existing redfams need to be updated |
|
|
|
redfam.update( articlesList, str(heading), redpage, isarchive, |
|
|
|
beginning, ending ) |
|
|
|
|
|
|
|
else: |
|
|
|
# Create the RedFam object |
|
|
|
redfam = RedFamParser( articlesList, str(heading), |
|
|
|
redpage, isarchive, beginning, ending ) |
|
|
|
|
|
|
|
# Add redfam to redpage object |
|
|
|
redpage.redfams.set( redfam ) |
|
|
|
|
|
|
|
@classmethod |
|
|
|
def extract_dates( cls, text, isarchive=False ): |
|
|
@ -599,42 +470,16 @@ class RedFamWorker( RedFam ): |
|
|
|
Handles working with redundance families stored in database |
|
|
|
where discussion is finished |
|
|
|
""" |
|
|
|
def __init__( self, mysql_data ): |
|
|
|
|
|
|
|
articlesList = [] |
|
|
|
|
|
|
|
for key in sorted( mysql_data.keys() ): |
|
|
|
if 'article' in key and 'status' not in key and mysql_data[ key ]: |
|
|
|
articlesList.append( mysql_data[ key ] ) |
|
|
|
|
|
|
|
# Preset article status list with empty sets for existing articles |
|
|
|
self._article_status = [set() for x in range(0, len(articlesList))] |
|
|
|
|
|
|
|
super().__init__( articlesList, mysql_data[ 'beginning' ], |
|
|
|
mysql_data[ 'ending' ], mysql_data[ 'redpageid' ], |
|
|
|
mysql_data[ 'status' ], mysql_data[ 'famhash' ], |
|
|
|
mysql_data[ 'heading' ] ) |
|
|
|
def __init__( self ): |
|
|
|
|
|
|
|
self._mysql.data = mysql_data |
|
|
|
|
|
|
|
# Set up article status |
|
|
|
index = 0 |
|
|
|
for article in self._articlesList: |
|
|
|
raw_status = mysql_data[ "article" + str(index) + "_status" ] |
|
|
|
if not raw_status: |
|
|
|
raw_status = str() |
|
|
|
self._article_parse_status( raw_status, index ) |
|
|
|
index += 1 |
|
|
|
|
|
|
|
# Get related RedPage-Information |
|
|
|
self.redpageid = mysql_data[ 'pageid' ] |
|
|
|
self.redpagetitle = mysql_data[ 'pagetitle' ] |
|
|
|
super().__init__() |
|
|
|
|
|
|
|
# Make sure locale is set to 'de_DE.UTF-8' to prevent problems |
|
|
|
# with wrong month abreviations in strptime |
|
|
|
locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8') |
|
|
|
|
|
|
|
def article_generator(self, filter_existing=None, filter_redirects=None, |
|
|
|
def article_generator(self, # noqa |
|
|
|
filter_existing=None, filter_redirects=None, |
|
|
|
exclude_article_status=[], |
|
|
|
onlyinclude_article_status=[] ): |
|
|
|
""" |
|
|
@ -653,8 +498,34 @@ class RedFamWorker( RedFam ): |
|
|
|
|
|
|
|
""" |
|
|
|
# Iterate over articles in redfam |
|
|
|
for article in self._articlesList: |
|
|
|
page = pywikibot.Page(pywikibot.Link(article), self.site) |
|
|
|
for article in self.articlesList: |
|
|
|
# Not all list elements contain articles |
|
|
|
if not article: |
|
|
|
break |
|
|
|
|
|
|
|
page = pywikibot.Page(pywikibot.Link(article), pywikibot.Site()) |
|
|
|
|
|
|
|
# Filter existing pages if requested with filter_existing=False |
|
|
|
if page.exists(): |
|
|
|
self.article_remove_status( "deleted", title=article ) |
|
|
|
if filter_existing is False: |
|
|
|
continue |
|
|
|
# Filter non existing Pages if requested with filter_existing=True |
|
|
|
else: |
|
|
|
self.article_add_status( "deleted", title=article ) |
|
|
|
if filter_existing: |
|
|
|
continue |
|
|
|
|
|
|
|
# Filter redirects if requested with filter_redirects=True |
|
|
|
if page.isRedirectPage(): |
|
|
|
self.article_add_status( "redirect", title=article ) |
|
|
|
if filter_redirects: |
|
|
|
continue |
|
|
|
# Filter noredirects if requested with filter_redirects=False |
|
|
|
else: |
|
|
|
self.article_remove_status("redirect", title=article ) |
|
|
|
if filter_redirects is False: |
|
|
|
continue |
|
|
|
|
|
|
|
# Exclude by article status |
|
|
|
for status in exclude_article_status: |
|
|
@ -666,20 +537,6 @@ class RedFamWorker( RedFam ): |
|
|
|
if not self.article_has_status( status, title=article ): |
|
|
|
continue |
|
|
|
|
|
|
|
# Filter non existing Pages if requested with filter_existing=True |
|
|
|
if filter_existing and not page.exists(): |
|
|
|
continue |
|
|
|
# Filter existing pages if requested with filter_existing=False |
|
|
|
elif filter_existing is False and page.exists(): |
|
|
|
continue |
|
|
|
|
|
|
|
# Filter redirects if requested with filter_redirects=True |
|
|
|
if filter_redirects and page.isRedirectPage(): |
|
|
|
continue |
|
|
|
# Filter noredirects if requested with filter_redirects=False |
|
|
|
elif filter_redirects is False and not page.isRedirectPage(): |
|
|
|
continue |
|
|
|
|
|
|
|
# Yield filtered pages |
|
|
|
yield page |
|
|
|
|
|
|
@ -687,24 +544,18 @@ class RedFamWorker( RedFam ): |
|
|
|
""" |
|
|
|
Sets status to 3 when worked on |
|
|
|
""" |
|
|
|
for article in self._articlesList: |
|
|
|
for article in self.articlesList: |
|
|
|
if not article: |
|
|
|
break |
|
|
|
|
|
|
|
if self.article_has_status( "note_rej", title=article ): |
|
|
|
self.add_status( "note_rej" ) |
|
|
|
self.status.add( "note_rej" ) |
|
|
|
if self.article_has_status( "sav_err", title=article ): |
|
|
|
self.add_status( "sav_err" ) |
|
|
|
|
|
|
|
if not self.has_status( "sav_err" ) and \ |
|
|
|
not self.has_status( "note_rej" ): |
|
|
|
self.add_status( "marked" ) |
|
|
|
self.status.add( "sav_err" ) |
|
|
|
|
|
|
|
self._mysql.data[ 'status' ] = self._raw_status() |
|
|
|
index = 0 |
|
|
|
for article in self._articlesList: |
|
|
|
self._mysql.data[ "article" + str(index) + 'status' ] = \ |
|
|
|
self._article_raw_status( index=index ) |
|
|
|
index += 1 |
|
|
|
|
|
|
|
print( repr(self) ) |
|
|
|
if not self.status.has( "sav_err" ) and \ |
|
|
|
not self.status.has( "note_rej" ): |
|
|
|
self.status.add( "marked" ) |
|
|
|
|
|
|
|
def get_disc_link( self ): |
|
|
|
""" |
|
|
@ -715,7 +566,7 @@ class RedFamWorker( RedFam ): |
|
|
|
""" |
|
|
|
|
|
|
|
# We need to Replace Links with their linktext |
|
|
|
anchor_code = mwparser.parse( self._mysql.data[ 'heading' ].strip() ) |
|
|
|
anchor_code = mwparser.parse( self.heading.strip() ) |
|
|
|
for link in anchor_code.ifilter_wikilinks(): |
|
|
|
if link.text: |
|
|
|
text = link.text |
|
|
@ -728,7 +579,7 @@ class RedFamWorker( RedFam ): |
|
|
|
anchor_code.replace( " ", "_" ) |
|
|
|
|
|
|
|
# We try it with out any more parsing as mw will do while parsing page |
|
|
|
return ( self.redpagetitle + "#" + |
|
|
|
return ( self.redpage.pagetitle + "#" + |
|
|
|
str(anchor_code).strip() ) |
|
|
|
|
|
|
|
def generate_disc_notice_template( self ): |
|
|
@ -748,7 +599,9 @@ class RedFamWorker( RedFam ): |
|
|
|
param_cnt = 3 |
|
|
|
|
|
|
|
# Iterate over articles in redfam |
|
|
|
for article in self._articlesList: |
|
|
|
for article in self.articlesList: |
|
|
|
if not article: |
|
|
|
break |
|
|
|
# Make sure to only use 8 articles (max. param 10) |
|
|
|
if param_cnt > 10: |
|
|
|
break |
|
|
@ -759,11 +612,11 @@ class RedFamWorker( RedFam ): |
|
|
|
param_cnt += 1 |
|
|
|
|
|
|
|
# Add begin |
|
|
|
begin = self._mysql.data[ 'beginning' ].strftime( "%B %Y" ) |
|
|
|
begin = self.beginning.strftime( "%B %Y" ) |
|
|
|
template.add( "Beginn", begin, True ) |
|
|
|
|
|
|
|
# Add end (if not same as begin) |
|
|
|
end = self._mysql.data[ 'ending' ].strftime( "%B %Y" ) |
|
|
|
end = self.ending.strftime( "%B %Y" ) |
|
|
|
if not end == begin: |
|
|
|
template.add( "Ende", end, True ) |
|
|
|
|
|
|
@ -795,13 +648,14 @@ class RedFamWorker( RedFam ): |
|
|
|
Yield red_fams stored in db by given status which have an ending after |
|
|
|
given one |
|
|
|
""" |
|
|
|
mysql = MysqlRedFam() |
|
|
|
for fam in mysql.get_by_status_and_ending( status, ending ): |
|
|
|
try: |
|
|
|
yield cls( fam ) |
|
|
|
except RedFamHashError: |
|
|
|
print(fam) |
|
|
|
raise |
|
|
|
for redfam in RedFamWorker.session.query(RedFamWorker).filter( |
|
|
|
# NOT WORKING WITH OBJECT NOTATION |
|
|
|
# RedFamWorker._status.like('archived'), |
|
|
|
# RedFamWorker._status.like("%{0:s}%".format(status)), |
|
|
|
text("status LIKE '%archived%'"), |
|
|
|
RedFamWorker.ending >= ending ): |
|
|
|
|
|
|
|
yield redfam |
|
|
|
|
|
|
|
|
|
|
|
class RedFamError( Exception ): |
|
|
|