Clean up PEP8 styleguide compatibility with flake8
This commit is contained in:
115
mysqlred.py
115
mysqlred.py
@@ -2,25 +2,25 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# mysqlred.py
|
# mysqlred.py
|
||||||
#
|
#
|
||||||
# Copyright 2015 GOLDERWEB – Jonathan Golder <jonathan@golderweb.de>
|
# Copyright 2015 GOLDERWEB – Jonathan Golder <jonathan@golderweb.de>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; either version 3 of the License, or
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
# MA 02110-1301, USA.
|
# MA 02110-1301, USA.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
"""
|
"""
|
||||||
Provides interface classes for communication of redundances bot with mysql-db
|
Provides interface classes for communication of redundances bot with mysql-db
|
||||||
"""
|
"""
|
||||||
@@ -33,6 +33,7 @@ except ImportError:
|
|||||||
|
|
||||||
from pywikibot import config
|
from pywikibot import config
|
||||||
|
|
||||||
|
|
||||||
class MysqlRed:
|
class MysqlRed:
|
||||||
"""
|
"""
|
||||||
Basic interface class, containing opening of connection
|
Basic interface class, containing opening of connection
|
||||||
@@ -40,12 +41,13 @@ class MysqlRed:
|
|||||||
Specific querys should be defined in descendant classes per data type
|
Specific querys should be defined in descendant classes per data type
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#Save mysqldb-connection as class attribute to use only one in descendant classes
|
# Save mysqldb-connection as class attribute to use only one
|
||||||
|
# in descendant classes
|
||||||
connection = False
|
connection = False
|
||||||
db_hostname=config.db_hostname
|
db_hostname = config.db_hostname
|
||||||
db_username=config.db_username
|
db_username = config.db_username
|
||||||
db_password=config.db_password
|
db_password = config.db_password
|
||||||
db_name=config.db_username + '__bot'
|
db_name = config.db_username + '__bot'
|
||||||
|
|
||||||
def __init__( self ):
|
def __init__( self ):
|
||||||
"""
|
"""
|
||||||
@@ -55,9 +57,13 @@ class MysqlRed:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Connect to mysqldb only once
|
# Connect to mysqldb only once
|
||||||
if( type( self ).connection == False ):
|
if not type( self ).connection:
|
||||||
|
|
||||||
type( self ).connection = mysqldb.connect( host=type( self ).db_hostname, user=type( self ).db_username, passwd=type( self ).db_password, db=type( self ).db_name )
|
type( self ).connection = mysqldb.connect(
|
||||||
|
host=type( self ).db_hostname,
|
||||||
|
user=type( self ).db_username,
|
||||||
|
passwd=type( self ).db_password,
|
||||||
|
db=type( self ).db_name )
|
||||||
|
|
||||||
def __del__( self ):
|
def __del__( self ):
|
||||||
"""
|
"""
|
||||||
@@ -66,10 +72,11 @@ class MysqlRed:
|
|||||||
|
|
||||||
type( self ).connection.close()
|
type( self ).connection.close()
|
||||||
|
|
||||||
|
|
||||||
class MysqlRedPage( MysqlRed ):
|
class MysqlRedPage( MysqlRed ):
|
||||||
"""
|
"""
|
||||||
MySQL-db Interface for handling querys for RedPages
|
MySQL-db Interface for handling querys for RedPages
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__( self, page_id ):
|
def __init__( self, page_id ):
|
||||||
"""
|
"""
|
||||||
@@ -78,7 +85,7 @@ class MysqlRedPage( MysqlRed ):
|
|||||||
|
|
||||||
super().__init__( )
|
super().__init__( )
|
||||||
|
|
||||||
self.__page_id = int( page_id );
|
self.__page_id = int( page_id )
|
||||||
|
|
||||||
self.data = self.get_page()
|
self.data = self.get_page()
|
||||||
|
|
||||||
@@ -91,13 +98,14 @@ class MysqlRedPage( MysqlRed ):
|
|||||||
|
|
||||||
@param int page_id MediaWiki page_id for page to retrieve
|
@param int page_id MediaWiki page_id for page to retrieve
|
||||||
|
|
||||||
@returns tuple Tuple with data for given page_id otherwise if none found
|
@returns tuple Tuple with data for given page_id
|
||||||
bool FALSE
|
bool FALSE if none found
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cursor = type( self ).connection.cursor(mysqldb.DictCursor)
|
cursor = type( self ).connection.cursor(mysqldb.DictCursor)
|
||||||
|
|
||||||
cursor.execute( 'SELECT * FROM `red_pages` WHERE `page_id` = ?;', ( self.__page_id, ) )
|
cursor.execute( 'SELECT * FROM `red_pages` WHERE `page_id` = ?;',
|
||||||
|
( self.__page_id, ) )
|
||||||
res = cursor.fetchone()
|
res = cursor.fetchone()
|
||||||
|
|
||||||
if res:
|
if res:
|
||||||
@@ -109,9 +117,9 @@ class MysqlRedPage( MysqlRed ):
|
|||||||
"""
|
"""
|
||||||
Inserts a red page row in MySQL-Database for given page_id
|
Inserts a red page row in MySQL-Database for given page_id
|
||||||
|
|
||||||
@param int rev_id MediaWiki current rev_id for page to update
|
@param int rev_id MediaWiki current rev_id
|
||||||
@param str page_title MediaWiki new page_title for page to update
|
@param str page_title MediaWiki new page_title
|
||||||
@param int status Page parsing status (0 - not (successfully) parsed; 1 - successfully parsed; 2 - successfully parsed archive)
|
@param int status Page parsing status
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cursor = type( self ).connection.cursor()
|
cursor = type( self ).connection.cursor()
|
||||||
@@ -121,8 +129,10 @@ class MysqlRedPage( MysqlRed ):
|
|||||||
if not rev_id:
|
if not rev_id:
|
||||||
rev_id = self.data[ 'rev_id' ]
|
rev_id = self.data[ 'rev_id' ]
|
||||||
|
|
||||||
query = 'INSERT INTO `red_pages` ( page_id, page_title, rev_id, status ) VALUES ( ?, ?, ?, ? );'
|
query = 'INSERT INTO `red_pages` \
|
||||||
data = ( self.__page_id, str( page_title ), int( rev_id ), int( status ) )
|
( page_id, page_title, rev_id, status ) \
|
||||||
|
VALUES ( ?, ?, ?, ? );'
|
||||||
|
data = ( self.__page_id, page_title, rev_id, status )
|
||||||
|
|
||||||
cursor.execute( query, data)
|
cursor.execute( query, data)
|
||||||
|
|
||||||
@@ -134,9 +144,9 @@ class MysqlRedPage( MysqlRed ):
|
|||||||
"""
|
"""
|
||||||
Updates the red page row in MySQL-Database for given page_id
|
Updates the red page row in MySQL-Database for given page_id
|
||||||
|
|
||||||
@param int rev_id MediaWiki current rev_id for page to update
|
@param int rev_id MediaWiki current rev_id
|
||||||
@param str page_title MediaWiki new page_title for page to update
|
@param str page_title MediaWiki new page_title
|
||||||
@param int status Page parsing status (0 - not (successfully) parsed; 1 - successfully parsed)
|
@param int status Page parsing status
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cursor = type( self ).connection.cursor()
|
cursor = type( self ).connection.cursor()
|
||||||
@@ -146,17 +156,20 @@ class MysqlRedPage( MysqlRed ):
|
|||||||
if not rev_id:
|
if not rev_id:
|
||||||
rev_id = self.data[ 'rev_id' ]
|
rev_id = self.data[ 'rev_id' ]
|
||||||
|
|
||||||
query = 'UPDATE `red_pages` SET `page_title` = ?, `rev_id` = ?, `status`= ? WHERE `page_id` = ?;'
|
query = 'UPDATE `red_pages` \
|
||||||
data = ( str( page_title ), int( rev_id ), int( status ), self.__page_id )
|
SET `page_title` = ?, `rev_id` = ?, `status`= ? \
|
||||||
|
WHERE `page_id` = ?;'
|
||||||
|
data = ( page_title, rev_id, status, self.__page_id )
|
||||||
|
|
||||||
cursor.execute( query, data)
|
cursor.execute( query, data)
|
||||||
|
|
||||||
type( self ).connection.commit()
|
type( self ).connection.commit()
|
||||||
|
|
||||||
|
|
||||||
class MysqlRedFam( MysqlRed ):
|
class MysqlRedFam( MysqlRed ):
|
||||||
"""
|
"""
|
||||||
MySQL-db Interface for handling querys for RedFams
|
MySQL-db Interface for handling querys for RedFams
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__( self, fam_hash ):
|
def __init__( self, fam_hash ):
|
||||||
"""
|
"""
|
||||||
@@ -176,13 +189,14 @@ class MysqlRedFam( MysqlRed ):
|
|||||||
"""
|
"""
|
||||||
Retrieves a red family row from MySQL-Database for given fam_hash
|
Retrieves a red family row from MySQL-Database for given fam_hash
|
||||||
|
|
||||||
@returns dict Dictionairy with data for given fam hash otherwise if none found
|
@returns dict Dictionairy with data for given fam hash
|
||||||
bool FALSE
|
False if none found
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cursor = type( self ).connection.cursor(mysqldb.DictCursor)
|
cursor = type( self ).connection.cursor( mysqldb.DictCursor )
|
||||||
|
|
||||||
cursor.execute( 'SELECT * FROM `red_families` WHERE `fam_hash` = ?;', ( self.__fam_hash, ) )
|
cursor.execute( 'SELECT * FROM `red_families` WHERE `fam_hash` = ?;',
|
||||||
|
( self.__fam_hash, ) )
|
||||||
res = cursor.fetchone()
|
res = cursor.fetchone()
|
||||||
|
|
||||||
if res:
|
if res:
|
||||||
@@ -190,12 +204,18 @@ class MysqlRedFam( MysqlRed ):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def add_fam( self, articlesList, heading, red_page_id, beginning, ending=None, status=0 ):
|
def add_fam( self, articlesList, heading, red_page_id,
|
||||||
|
beginning, ending=None, status=0 ):
|
||||||
|
|
||||||
cursor = type( self ).connection.cursor()
|
cursor = type( self ).connection.cursor()
|
||||||
|
|
||||||
query = 'INSERT INTO `red_families` ( fam_hash, red_page_id, beginning, ending, status, heading, article0, article1, article2, article3, article4, article5, article6, article7 ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? );'
|
query = 'INSERT INTO `red_families` \
|
||||||
data = [ str( self.__fam_hash ), red_page_id, beginning, ending, status, heading ]
|
( fam_hash, red_page_id, beginning, ending, status, heading, \
|
||||||
|
article0, article1, article2, article3, \
|
||||||
|
article4, article5, article6, article7 ) \
|
||||||
|
VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? );'
|
||||||
|
data = [ self.__fam_hash, red_page_id, beginning, ending,
|
||||||
|
status, heading ]
|
||||||
|
|
||||||
for article in articlesList:
|
for article in articlesList:
|
||||||
data.append( str( article ) )
|
data.append( str( article ) )
|
||||||
@@ -215,16 +235,19 @@ class MysqlRedFam( MysqlRed ):
|
|||||||
"""
|
"""
|
||||||
Updates the red fam row in MySQL-Database for given fam_hash
|
Updates the red fam row in MySQL-Database for given fam_hash
|
||||||
|
|
||||||
@param int red_page_id MediaWiki page_id which contains red_fam
|
@param int red_page_id MediaWiki page_id
|
||||||
@param datetime beginning Timestamp of beginning of redundance discussion
|
@param datetime beginning Timestamp of beginning
|
||||||
qparam datetime ending Timestamp of ending of redundance discussion
|
qparam datetime ending Timestamp of ending of
|
||||||
@param int status red_fam status (0 - discussion is running; 1 - discussion over; 2 - discussion archived)
|
@param int status red_fam status
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cursor = type( self ).connection.cursor()
|
cursor = type( self ).connection.cursor()
|
||||||
|
|
||||||
query = 'UPDATE `red_families` SET `red_page_id` = ?, `heading` = ?, `beginning` = ?, `ending` = ?, `status`= ? WHERE `fam_hash` = ?;'
|
query = 'UPDATE `red_families` \
|
||||||
data = ( int(red_page_id ), str( heading ), beginning, ending, int( status ), self.__fam_hash )
|
SET `red_page_id` = ?, `heading` = ?, `beginning` = ?, \
|
||||||
|
`ending` = ?, `status`= ? WHERE `fam_hash` = ?;'
|
||||||
|
data = ( red_page_id, heading, beginning,
|
||||||
|
ending, status, self.__fam_hash )
|
||||||
|
|
||||||
cursor.execute( query, data)
|
cursor.execute( query, data)
|
||||||
|
|
||||||
|
|||||||
184
redfam.py
184
redfam.py
@@ -2,64 +2,54 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# redfam.py
|
# redfam.py
|
||||||
#
|
#
|
||||||
# Copyright 2015 GOLDERWEB – Jonathan Golder <jonathan@golderweb.de>
|
# Copyright 2015 GOLDERWEB – Jonathan Golder <jonathan@golderweb.de>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; either version 3 of the License, or
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
# MA 02110-1301, USA.
|
# MA 02110-1301, USA.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
"""
|
"""
|
||||||
Provides classes for working with RedFams
|
Provides classes for working with RedFams
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import re
|
|
||||||
import locale
|
import locale
|
||||||
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import pywikibot
|
import pywikibot
|
||||||
|
|
||||||
from mysqlred import MysqlRedFam
|
from mysqlred import MysqlRedFam
|
||||||
|
|
||||||
|
|
||||||
class RedFam:
|
class RedFam:
|
||||||
"""
|
"""
|
||||||
Basic class for RedFams, containing the basic data structure
|
Basic class for RedFams, containing the basic data structure
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__( self, fam_hash=None, articlesList=None, red_page_id=None, beginning=None, ending=None, status=0 ):
|
def __init__( self, fam_hash=None, articlesList=None, red_page_id=None,
|
||||||
|
beginning=None, ending=None, status=0 ):
|
||||||
"""
|
"""
|
||||||
Generates a new RedFam object
|
Generates a new RedFam object
|
||||||
|
|
||||||
@param articlesList list List of articles of redundance family
|
@param articlesList list List of articles
|
||||||
@param beginning datetime Beginning date of redundance diskussion
|
@param beginning datetime Beginning date
|
||||||
@param ending datetime Ending date of redundance diskussion
|
@param ending datetime Ending date
|
||||||
"""
|
"""
|
||||||
|
pass
|
||||||
#if( beginning ):
|
|
||||||
# self.add_beginning( beginning )
|
|
||||||
# self._beginning = None
|
|
||||||
|
|
||||||
#if( ending ):
|
|
||||||
# self.add_ending( ending )
|
|
||||||
#else:
|
|
||||||
# self._ending = None
|
|
||||||
|
|
||||||
#self._status = status # __TODO__ STATUS CODE
|
|
||||||
|
|
||||||
#self._handle_db()
|
|
||||||
|
|
||||||
def __repr__( self ):
|
def __repr__( self ):
|
||||||
|
|
||||||
@@ -73,13 +63,16 @@ class RedFam:
|
|||||||
else:
|
else:
|
||||||
ending = ""
|
ending = ""
|
||||||
|
|
||||||
__repr = "RedFam( " + repr( self._articlesList ) + beginning + ending + ", status=" + repr( self._status ) + " )"
|
__repr = "RedFam( " + repr( self._articlesList ) + beginning +\
|
||||||
|
ending + ", status=" + repr( self._status ) + " )"
|
||||||
|
|
||||||
return __repr
|
return __repr
|
||||||
|
|
||||||
|
|
||||||
class RedFamParser( RedFam ):
|
class RedFamParser( RedFam ):
|
||||||
"""
|
"""
|
||||||
Provides an interface to RedFam for adding/updating redundance families while parsig redundance pages
|
Provides an interface to RedFam for adding/updating redundance families
|
||||||
|
while parsig redundance pages
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Define the timestamp format
|
# Define the timestamp format
|
||||||
@@ -89,26 +82,29 @@ class RedFamParser( RedFam ):
|
|||||||
__sectionhead_pat = re.compile( r"^(=+)(.*\[\[.+\]\].*\[\[.+\]\].*)\1" )
|
__sectionhead_pat = re.compile( r"^(=+)(.*\[\[.+\]\].*\[\[.+\]\].*)\1" )
|
||||||
|
|
||||||
# Define timestamp re.pattern
|
# Define timestamp re.pattern
|
||||||
__timestamp_pat = re.compile( r"(\d{2}:\d{2}), (\d{1,2}). (Jan|Feb|Mär|Apr|Mai|Jun|Jul|Aug|Sep|Okt|Nov|Dez).? (\d{4})" )
|
__timestamp_pat = re.compile( r"(\d{2}:\d{2}), (\d{1,2}). (Jan|Feb|Mär|Apr|Mai|Jun|Jul|Aug|Sep|Okt|Nov|Dez).? (\d{4})" ) # noqa
|
||||||
|
|
||||||
# Textpattern for recognisation of done-notices
|
# Textpattern for recognisation of done-notices
|
||||||
__done_notice = ":<small>Archivierung dieses Abschnittes wurde gewünscht von:"
|
__done_notice = ":<small>Archivierung dieses Abschnittes \
|
||||||
|
wurde gewünscht von:"
|
||||||
__done_notice2 = "{{Erledigt|"
|
__done_notice2 = "{{Erledigt|"
|
||||||
|
|
||||||
def __init__( self, heading, red_page_id, red_page_archive, beginning, ending=None ):
|
def __init__( self, heading, red_page_id, red_page_archive,
|
||||||
|
beginning, ending=None ):
|
||||||
"""
|
"""
|
||||||
Creates a RedFam object based on data collected while parsing red_pages combined with possibly former known data from db
|
Creates a RedFam object based on data collected while parsing red_pages
|
||||||
|
combined with possibly former known data from db
|
||||||
|
|
||||||
@param red_fam_heading string String with wikitext heading of redundance section
|
@param red_fam_heading str Wikitext heading of section
|
||||||
@param red_page_id int MediaWiki page_id of red_page containing red_fam
|
@param red_page_id int MediaWiki page_id
|
||||||
@param red_page_archive bool Is red_page an archive
|
@param red_page_archive bool Is red_page an archive
|
||||||
@param beginning datetime Timestamp of beginning of redundance discussion
|
@param beginning datetime Timestamp of beginning
|
||||||
string Timestamp of beginning of redundance discussion as srftime parseable string
|
str as strptime parseable string
|
||||||
@param ending datetime Timestamp of ending of redundance discussion
|
@param ending datetime Timestamp of ending
|
||||||
string Timestamp of ending of redundance discussion as srftime parseable string
|
str strptime parseable string
|
||||||
"""
|
"""
|
||||||
|
|
||||||
## Set object attributes:
|
# Set object attributes:
|
||||||
self._red_page_id = red_page_id
|
self._red_page_id = red_page_id
|
||||||
self._red_page_archive = red_page_archive
|
self._red_page_archive = red_page_archive
|
||||||
|
|
||||||
@@ -119,18 +115,21 @@ class RedFamParser( RedFam ):
|
|||||||
if( ending ):
|
if( ending ):
|
||||||
self.add_ending( ending )
|
self.add_ending( ending )
|
||||||
else:
|
else:
|
||||||
#If no ending was provided set to None
|
# If no ending was provided set to None
|
||||||
self._ending = None
|
self._ending = None
|
||||||
|
|
||||||
self._status = None
|
self._status = None
|
||||||
|
|
||||||
# Parse the provided heading of redundance section to set self._articlesList
|
# Parse the provided heading of redundance section
|
||||||
|
# to set self._articlesList
|
||||||
self.heading_parser( heading )
|
self.heading_parser( heading )
|
||||||
|
|
||||||
# Calculates the sha1 hash over self._articlesList to rediscover known redundance families
|
# Calculates the sha1 hash over self._articlesList to
|
||||||
|
# rediscover known redundance families
|
||||||
self.fam_hash()
|
self.fam_hash()
|
||||||
|
|
||||||
# Open database connection, ask for data if existing, otherwise create entry
|
# Open database connection, ask for data if existing,
|
||||||
|
# otherwise create entry
|
||||||
self.__handle_db()
|
self.__handle_db()
|
||||||
|
|
||||||
# Check status changes
|
# Check status changes
|
||||||
@@ -148,7 +147,9 @@ class RedFamParser( RedFam ):
|
|||||||
self.__mysql = MysqlRedFam( self._fam_hash )
|
self.__mysql = MysqlRedFam( self._fam_hash )
|
||||||
|
|
||||||
if not self.__mysql.data:
|
if not self.__mysql.data:
|
||||||
self.__mysql.add_fam( self._articlesList, self._heading, self._red_page_id, self._beginning, self._ending )
|
self.__mysql.add_fam( self._articlesList, self._heading,
|
||||||
|
self._red_page_id, self._beginning,
|
||||||
|
self._ending )
|
||||||
|
|
||||||
def heading_parser( self, heading ):
|
def heading_parser( self, heading ):
|
||||||
"""
|
"""
|
||||||
@@ -165,12 +166,20 @@ class RedFamParser( RedFam ):
|
|||||||
else:
|
else:
|
||||||
raise ValueError( "Heading is not valid" )
|
raise ValueError( "Heading is not valid" )
|
||||||
|
|
||||||
# We get the pages in first [0] element iterating over wikilink_pat.findall( line )
|
# We get the pages in first [0] element iterating over
|
||||||
self._articlesList = [ link[0] for link in wikilink_pat.findall( self._heading ) ]
|
# wikilink_pat.findall( line )
|
||||||
|
self._articlesList = [ link[0] for link
|
||||||
|
in wikilink_pat.findall( self._heading ) ]
|
||||||
|
|
||||||
# Catch sections with more then 8 articles, print error
|
# Catch sections with more then 8 articles, print error
|
||||||
if len( self._articlesList ) > 8:
|
if len( self._articlesList ) > 8:
|
||||||
pywikibot.output( "{datetime} – \03{{lightred}}[WARNING] – 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 (%Z)"), number=len( self._articlesList ), repress=repr( self ) ) )
|
pywikibot.output( "{datetime} – \03{{lightred}}[WARNING] – \
|
||||||
|
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 ) ) )
|
||||||
|
|
||||||
self._articlesList = self._articlesList[:8]
|
self._articlesList = self._articlesList[:8]
|
||||||
|
|
||||||
def fam_hash( self ):
|
def fam_hash( self ):
|
||||||
@@ -178,58 +187,61 @@ class RedFamParser( RedFam ):
|
|||||||
Calculates the SHA-1 hash for the articlesList of redundance family.
|
Calculates the SHA-1 hash for the articlesList of redundance family.
|
||||||
Since we don't need security SHA-1 is just fine.
|
Since we don't need security SHA-1 is just fine.
|
||||||
|
|
||||||
@returns str String with the hexadecimal hash digest
|
@returns str String with the hexadecimal hash digest
|
||||||
"""
|
"""
|
||||||
|
|
||||||
h = hashlib.sha1()
|
h = hashlib.sha1()
|
||||||
h.update( str( self._articlesList ).encode('utf-8') )
|
h.update( str( self._articlesList ).encode('utf-8') )
|
||||||
|
|
||||||
self._fam_hash= h.hexdigest()
|
self._fam_hash = h.hexdigest()
|
||||||
|
|
||||||
def add_beginning( self, beginning ):
|
def add_beginning( self, beginning ):
|
||||||
"""
|
"""
|
||||||
Adds the beginning date of a redundance diskussion to the object and sets changed to True
|
Adds the beginning date of a redundance diskussion to the object
|
||||||
|
|
||||||
@param datetime datetime Beginning date of redundance diskussion
|
@param datetime datetime Beginning date
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self._beginning = self.__datetime( beginning )
|
self._beginning = self.__datetime( beginning )
|
||||||
|
|
||||||
def add_ending( self, ending ):
|
def add_ending( self, ending ):
|
||||||
"""
|
"""
|
||||||
Adds the ending date of a redundance diskussion to the object. Also sets the status to __TODO__ STATUS NUMBER and changed to True
|
Adds the ending date of a redundance diskussion to the object.
|
||||||
|
|
||||||
@param datetime datetime Ending date of redundance diskussion
|
@param datetime datetime Ending date
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self._ending = self.__datetime( ending )
|
self._ending = self.__datetime( ending )
|
||||||
|
|
||||||
def __datetime( self, timestamp ):
|
def __datetime( self, timestamp ):
|
||||||
"""
|
"""
|
||||||
Decides wether given timestamp is a parseable string or a datetime object and returns a datetime object in both cases
|
Decides wether given timestamp is a parseable string or a
|
||||||
|
datetime object and returns a datetime object in both cases
|
||||||
|
|
||||||
@param datetime timestamp Datetime object
|
@param datetime timestamp Datetime object
|
||||||
str timestamp Parseable string with timestamp in format __timestamp_format
|
str timestamp Parseable string with timestamp
|
||||||
|
|
||||||
@returns datetime Datetime object
|
@returns datetime Datetime object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Make sure locale is set to 'de_DE.UTF-8' to prevent problems with wrong month abreviations in strptime
|
# 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')
|
locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')
|
||||||
|
|
||||||
if( isinstance( timestamp, datetime ) ):
|
if( isinstance( timestamp, datetime ) ):
|
||||||
return timestamp
|
return timestamp
|
||||||
else:
|
else:
|
||||||
result = datetime.strptime( timestamp, type( self ).__timestamp_format )
|
result = datetime.strptime( timestamp,
|
||||||
|
type( self ).__timestamp_format )
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def status( self ):
|
def status( self ):
|
||||||
"""
|
"""
|
||||||
Handles detection of correct status
|
Handles detection of correct status
|
||||||
There are three possible stati:
|
There are three possible stati:
|
||||||
- 0 Discussion is running --> no ending, page is not an archive
|
- 0 Discussion running --> no ending, page is not an archive
|
||||||
- 1 Discussion is over --> ending present, page is not an archive
|
- 1 Discussion over --> ending present, page is not an archive
|
||||||
- 2 Discussion is archived --> ending (normaly) present, page is an archive
|
- 2 Discussion archived --> ending (normaly) present, page is archive
|
||||||
- 3 and greater status was set by worker script, do not change it
|
- 3 and greater status was set by worker script, do not change it
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -247,22 +259,28 @@ class RedFamParser( RedFam ):
|
|||||||
self._status = 2
|
self._status = 2
|
||||||
else:
|
else:
|
||||||
self._status = self.__mysql.data[ 'status' ]
|
self._status = self.__mysql.data[ 'status' ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def changed( self ):
|
def changed( self ):
|
||||||
"""
|
"""
|
||||||
Checks wether anything has changed and maybe triggers db update
|
Checks wether anything has changed and maybe triggers db update
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# On archived red_fams do not delete possibly existing ending
|
# On archived red_fams do not delete possibly existing ending
|
||||||
if not self._ending and self._status > 1 and self.__mysql.data[ 'ending' ]:
|
if( not self._ending and self._status > 1
|
||||||
self._ending = self.__mysql.data[ 'ending' ]
|
and self.__mysql.data[ 'ending' ] ):
|
||||||
|
|
||||||
|
self._ending = self.__mysql.data[ 'ending' ]
|
||||||
|
|
||||||
# Since status change means something has changed, update database
|
# Since status change means something has changed, update database
|
||||||
if( self._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[ 'red_page_id' ] or self._heading != self.__mysql.data[ 'heading' ]):
|
if( self._status != self.__mysql.data[ 'status' ] or
|
||||||
self.__mysql.update_fam( self._red_page_id, self._heading, self._beginning, self._ending, self._status )
|
self._beginning != self.__mysql.data[ 'beginning' ] or
|
||||||
|
self._ending != self.__mysql.data[ 'ending' ] or
|
||||||
|
self._red_page_id != self.__mysql.data[ 'red_page_id' ] or
|
||||||
|
self._heading != self.__mysql.data[ 'heading' ]):
|
||||||
|
|
||||||
|
self.__mysql.update_fam( self._red_page_id, self._heading,
|
||||||
|
self._beginning, self._ending,
|
||||||
|
self._status )
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_sectionheading( cls, line ):
|
def is_sectionheading( cls, line ):
|
||||||
@@ -271,7 +289,7 @@ class RedFamParser( RedFam ):
|
|||||||
|
|
||||||
@param str line String to check
|
@param str line String to check
|
||||||
|
|
||||||
@returns bool Returns True if it is a section heading, otherwise false
|
@returns bool Returns True if it is a section heading
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if cls.__sectionhead_pat.search( line ):
|
if cls.__sectionhead_pat.search( line ):
|
||||||
@@ -291,8 +309,10 @@ class RedFamParser( RedFam ):
|
|||||||
|
|
||||||
match = cls.__timestamp_pat.search( line )
|
match = cls.__timestamp_pat.search( line )
|
||||||
if match:
|
if match:
|
||||||
# Since some timestamps are broken we need to reconstruct them by regex match groups
|
# Since some timestamps are broken we need to reconstruct them
|
||||||
result = match.group(1) + ", " + match.group(2) + ". " + match.group(3) + ". " + match.group(4)
|
# by regex match groups
|
||||||
|
result = match.group(1) + ", " + match.group(2) + ". " +\
|
||||||
|
match.group(3) + ". " + match.group(4)
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
@@ -301,16 +321,18 @@ class RedFamParser( RedFam ):
|
|||||||
def is_ending( cls, line ):
|
def is_ending( cls, line ):
|
||||||
"""
|
"""
|
||||||
Returns the timestamp of done notice ( if one ), otherwise None
|
Returns the timestamp of done notice ( if one ), otherwise None
|
||||||
@param str line String to search in
|
@param str line String to search in
|
||||||
|
|
||||||
@returns str Timestamp, otherwise None
|
@returns str Timestamp, otherwise None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if ( cls.__done_notice in line ) or ( cls.__done_notice2 in line ):
|
if ( cls.__done_notice in line ) or ( cls.__done_notice2 in line ):
|
||||||
match = cls.__timestamp_pat.search( line )
|
match = cls.__timestamp_pat.search( line )
|
||||||
if match:
|
if match:
|
||||||
# Since some timestamps are broken we need to reconstruct them by regex match groups
|
# Since some timestamps are broken we need to reconstruct them
|
||||||
result = match.group(1) + ", " + match.group(2) + ". " + match.group(3) + ". " + match.group(4)
|
# by regex match groups
|
||||||
|
result = match.group(1) + ", " + match.group(2) + ". " +\
|
||||||
|
match.group(3) + ". " + match.group(4)
|
||||||
return result
|
return result
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -325,14 +347,18 @@ class RedFamParser( RedFam ):
|
|||||||
|
|
||||||
matches = cls.__timestamp_pat.findall( line )
|
matches = cls.__timestamp_pat.findall( line )
|
||||||
if matches:
|
if matches:
|
||||||
# Since some timestamps are broken we need to reconstruct them by regex match groups
|
# Since some timestamps are broken we need to reconstruct them
|
||||||
result = matches[-1][0] + ", " + matches[-1][1] + ". " + matches[-1][2] + ". " + matches[-1][3]
|
# by regex match groups
|
||||||
|
result = matches[-1][0] + ", " + matches[-1][1] + ". " +\
|
||||||
|
matches[-1][2] + ". " + matches[-1][3]
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class RedFamWorker( RedFam ):
|
class RedFamWorker( RedFam ):
|
||||||
"""
|
"""
|
||||||
Handles working with redundance families stored in database where discussion is finished
|
Handles working with redundance families stored in database
|
||||||
|
where discussion is finished
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|||||||
46
redpage.py
46
redpage.py
@@ -2,34 +2,35 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# redpage.py
|
# redpage.py
|
||||||
#
|
#
|
||||||
# Copyright 2015 GOLDERWEB – Jonathan Golder <jonathan@golderweb.de>
|
# Copyright 2015 GOLDERWEB – Jonathan Golder <jonathan@golderweb.de>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; either version 3 of the License, or
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
# MA 02110-1301, USA.
|
# MA 02110-1301, USA.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
"""
|
"""
|
||||||
Provides a class for handling redundance discussion pages and archives
|
Provides a class for handling redundance discussion pages and archives
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pywikibot
|
import pywikibot # noqa
|
||||||
|
|
||||||
from mysqlred import MysqlRedPage
|
from mysqlred import MysqlRedPage
|
||||||
from redfam import RedFamParser
|
from redfam import RedFamParser
|
||||||
|
|
||||||
|
|
||||||
class RedPage:
|
class RedPage:
|
||||||
"""
|
"""
|
||||||
Class for handling redundance discussion pages and archives
|
Class for handling redundance discussion pages and archives
|
||||||
@@ -39,7 +40,7 @@ class RedPage:
|
|||||||
"""
|
"""
|
||||||
Generate a new RedPage object based on the given pywikibot page object
|
Generate a new RedPage object based on the given pywikibot page object
|
||||||
|
|
||||||
@param page page Pywikibot/MediaWiki page object for page to work on
|
@param page page Pywikibot/MediaWiki page object for page
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Safe the pywikibot page object
|
# Safe the pywikibot page object
|
||||||
@@ -72,7 +73,10 @@ class RedPage:
|
|||||||
Check wether the page was changed since last run
|
Check wether the page was changed since last run
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if( self.__mysql.data != { 'page_id': self.page._pageid, 'rev_id': self.page._revid, 'page_title': self.page.title(), 'status': self.__mysql.data[ 'status' ] } ):
|
if( self.__mysql.data != { 'page_id': self.page._pageid,
|
||||||
|
'rev_id': self.page._revid,
|
||||||
|
'page_title': self.page.title(),
|
||||||
|
'status': self.__mysql.data[ 'status' ] } ):
|
||||||
self._changed = True
|
self._changed = True
|
||||||
else:
|
else:
|
||||||
self._changed = False
|
self._changed = False
|
||||||
@@ -82,10 +86,13 @@ class RedPage:
|
|||||||
Detects wether current page is an archive of discussions
|
Detects wether current page is an archive of discussions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self._archive or ( u"/Archiv" in self.page.title() ) or ( "{{Archiv}}" in self.page.text ) or ( "{{Archiv|" in self.page.text ):
|
if( self._archive or ( u"/Archiv" in self.page.title() ) or
|
||||||
return True
|
( "{{Archiv}}" in self.page.text ) or
|
||||||
|
( "{{Archiv|" in self.page.text ) ):
|
||||||
|
|
||||||
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def parse( self ):
|
def parse( self ):
|
||||||
"""
|
"""
|
||||||
@@ -108,7 +115,7 @@ class RedPage:
|
|||||||
# Iterate over the lines of the page
|
# Iterate over the lines of the page
|
||||||
for line in text_lines:
|
for line in text_lines:
|
||||||
|
|
||||||
# Check wether we have an "Redundance-Family"-Section heading (Level 3)
|
# Check wether we have an "Redundance-Family"-Section heading
|
||||||
if RedFamParser.is_sectionheading( line ):
|
if RedFamParser.is_sectionheading( line ):
|
||||||
|
|
||||||
# Save line number for last detected Redundance-Family
|
# Save line number for last detected Redundance-Family
|
||||||
@@ -120,16 +127,18 @@ class RedPage:
|
|||||||
beginning = None
|
beginning = None
|
||||||
ending = None
|
ending = None
|
||||||
|
|
||||||
# Check wether we are currently in an "Redundance-Family"-Section Body
|
# Check wether we are currently in an "Redundance-Family"-Section
|
||||||
if i > last_fam and last_fam > 0:
|
if i > last_fam and last_fam > 0:
|
||||||
|
|
||||||
# Check if we have alredy recognized the beginning date of the discussion (in former iteration) or if we have a done-notice
|
# Check if we have alredy recognized the beginning date of the
|
||||||
|
# discussion (in former iteration) or if we have a done-notice
|
||||||
if not beginning:
|
if not beginning:
|
||||||
beginning = RedFamParser.is_beginning( line )
|
beginning = RedFamParser.is_beginning( line )
|
||||||
elif not ending:
|
elif not ending:
|
||||||
ending = RedFamParser.is_ending( line )
|
ending = RedFamParser.is_ending( line )
|
||||||
|
|
||||||
# Detect end of red_fam section (next line is new sectionheading) or end of file
|
# Detect end of red_fam section (next line is new sectionheading)
|
||||||
|
# or end of file
|
||||||
# Prevent from running out of index
|
# Prevent from running out of index
|
||||||
if i < (length - 1):
|
if i < (length - 1):
|
||||||
test = RedFamParser.is_sectionheading( text_lines[ i + 1 ] )
|
test = RedFamParser.is_sectionheading( text_lines[ i + 1 ] )
|
||||||
@@ -140,7 +149,8 @@ class RedPage:
|
|||||||
# Create the red_fam object
|
# Create the red_fam object
|
||||||
if( fam_heading and beginning ):
|
if( fam_heading and beginning ):
|
||||||
|
|
||||||
#Maybe we can find a ending by feed if we have None yet (No done notice on archive pages)
|
# Maybe we can find a ending by feed if we have None yet
|
||||||
|
# (No done notice on archive pages)
|
||||||
if not ending and self.is_archive():
|
if not ending and self.is_archive():
|
||||||
j = i
|
j = i
|
||||||
while (j > last_fam) and not ending:
|
while (j > last_fam) and not ending:
|
||||||
@@ -148,7 +158,9 @@ class RedPage:
|
|||||||
ending = RedFamParser.is_ending2( text_lines[ j ] )
|
ending = RedFamParser.is_ending2( text_lines[ j ] )
|
||||||
|
|
||||||
# Create the RedFam object
|
# Create the RedFam object
|
||||||
red_fam = RedFamParser( fam_heading, self.page._pageid, self.is_archive(), beginning, ending )
|
red_fam = RedFamParser( fam_heading, self.page._pageid,
|
||||||
|
self.is_archive(), beginning,
|
||||||
|
ending )
|
||||||
|
|
||||||
# Increment line counter
|
# Increment line counter
|
||||||
i += 1
|
i += 1
|
||||||
|
|||||||
Reference in New Issue
Block a user