Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

230 righe
8.0 KiB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. #
  4. # charts.py
  5. #
  6. # Copyright 2015 GOLDERWEB – Jonathan Golder <jonathan@golderweb.de>
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 3 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with this program; if not, write to the Free Software
  20. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  21. # MA 02110-1301, USA.
  22. #
  23. #
  24. """
  25. Provides a class for handling chart lists
  26. """
  27. from datetime import datetime, timedelta
  28. import locale
  29. from isoweek import Week
  30. import pywikibot # noqa
  31. import mwparserfromhell as mwparser
  32. class Charts:
  33. """
  34. Class for handling chart lists
  35. """
  36. def __init__( self ):
  37. """
  38. Generate a new ChartsList object based on given pywikibot page object
  39. @param page page Pywikibot/MediaWiki page object for page
  40. """
  41. # Set locale to 'de_DE.UTF-8'
  42. locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')
  43. self.site = pywikibot.Site()
  44. self.changed = None
  45. # Safe the pywikibot page object
  46. # self.page = page
  47. self.open_overview()
  48. self.parse_overview()
  49. if self.changed:
  50. self.save_overview()
  51. def parse_charts_list( self, page ):
  52. """
  53. Handles the parsing process
  54. """
  55. # Parse charts list with mwparser
  56. wikicode = mwparser.parse( page.text )
  57. # Select the section "Singles"
  58. singles_section = wikicode.get_sections( matches="Singles" )[0]
  59. # Select the last occurence of template "Nummer-eins-Hits Zeile" in
  60. # "Singles"-section
  61. last_entry = singles_section.ifilter_templates(
  62. matches="Nummer-eins-Hits Zeile" )
  63. for last in last_entry:
  64. pass
  65. # Detect weather we have a date or a weeknumber for Template Param
  66. # "Chartein"
  67. if( last.get("Chartein").value.strip().isnumeric() ):
  68. chartein = last.get("Chartein").value.strip()
  69. else:
  70. chartein = datetime.strptime( last.get("Chartein").value.strip(),
  71. "%Y-%m-%d" )
  72. title = last.get("Titel").value.strip()
  73. interpret = last.get("Interpret").value.strip()
  74. # Return collected data as tuple
  75. return ( chartein, title, interpret )
  76. def parse_overview( self ):
  77. """
  78. Parses the given Charts-Overview-Page and returns the updated version
  79. """
  80. # Parse text with mwparser to get access to nodes
  81. wikicode = mwparser.parse( self.overview_text )
  82. # Get mwparser.template objects for Template "/Eintrag"
  83. for country in wikicode.ifilter_templates( matches="/Eintrag" ):
  84. # Get mwparser.wikilink object
  85. for link in country.get("Liste").value.ifilter_wikilinks():
  86. # Create Page-Object for Chartslist
  87. list_page = pywikibot.Page( self.site, link.title )
  88. # Only use first wikilink in Template Param "Liste"
  89. break
  90. # Check if we have a saved revid
  91. if not country.has( "Liste Revision" ):
  92. try:
  93. country.add( "Liste Revision", 0, before="Interpret" )
  94. except ValueError:
  95. country.add( "Liste Revision", 0 )
  96. # Check if saved revid is unequal current revid
  97. if( int( str( country.get( "Liste Revision" ).value ) ) !=
  98. list_page.latest_revision_id ):
  99. country = self.update_overview( country, list_page )
  100. # If any param of any occurence of Template "/Eintrag" has changed,
  101. # Save new version
  102. # We need to convert mwparser-objects to string before saving
  103. self.overview_text = str( wikicode )
  104. def open_overview( self ):
  105. """
  106. Opens the Charts-Overview-Page
  107. """
  108. with open( "/home/joni/GOLDERWEB/Daten/Projekte/05_Wikimedia/62_BOT/bot/charts/test-data.wiki", "r" ) as fr: # noqa
  109. self.overview_text = fr.read()
  110. def update_overview( self, country, list_page ): # noqa
  111. """
  112. Updates the templates given in county using data from given list_page
  113. @param country wikicode-object with Template for country
  114. @param list_page pywikibot-page-object for list-page
  115. @returns wikicode-object with updated Template for country
  116. """
  117. # Parse linked charts list for the country
  118. data = self.parse_charts_list( list_page )
  119. # Update "Liste Revision" param
  120. self.changed = True
  121. country.get( "Liste Revision" ).value = str(
  122. list_page.latest_revision_id )
  123. # For some countries we have weeknumbers instead of dates
  124. if( isinstance( data[0], str ) ):
  125. # Slice year out of link destination
  126. year = int( list_page.title()[-5:-1] )
  127. # Check if we have a param "Wochentag", otherwise add
  128. if not country.has( "Wochentag" ):
  129. country.add( "Wochentag", "" )
  130. if( str( country.get( "Wochentag" ).value ).isnumeric() ):
  131. days = int( str( country.get( "Wochentag" ).value ) )
  132. else:
  133. days = 0
  134. # Calculate date of monday in given week and add number of
  135. # days given in Template parameter "Wochentag" with monday
  136. # as day (zero)
  137. # We need double conversion since wikicode could not be casted
  138. # as int directly
  139. date = ( Week( year, int( data[0] ) ).monday() +
  140. timedelta( days=days ) )
  141. # Param Chartein contains a regular date
  142. else:
  143. date = data[0]
  144. # Check if param "Chartein" is present
  145. if not country.has( "Chartein" ):
  146. try:
  147. country.add( "Chartein", "", before="Wochentag" )
  148. except ValueError:
  149. country.add( "Chartein", "" )
  150. # Check if date has changed
  151. if( date.strftime( "%d. %B" ).lstrip( "0" ) !=
  152. country.get("Chartein").value ):
  153. self.changed = True
  154. country.get("Chartein").value = date.strftime( "%d. %B"
  155. ).lstrip( "0" )
  156. # Check if param "Titel" is present
  157. if not country.has( "Titel" ):
  158. country.add( "Titel", "", before="Chartein" )
  159. # Check if Titel has changed
  160. if( data[1] != country.get( "Titel" ).value ):
  161. self.changed = True
  162. country.get( "Titel" ).value = data[1]
  163. # Check if param "Intepret" is present
  164. if not country.has( "Interpret" ):
  165. country.add( "Interpret", "", before="Titel" )
  166. # Check if Interpret has changed
  167. if( data[2] != country.get( "Interpret" ).value ):
  168. self.changed = True
  169. country.get( "Interpret" ).value = data[2]
  170. def save_overview( self ):
  171. """
  172. Saves the current version of overview-text
  173. """
  174. with open( "/home/joni/GOLDERWEB/Daten/Projekte/05_Wikimedia/62_BOT/bot/charts/test-data.wiki", "w" ) as fw: # noqa
  175. fw.write( self.overview_text )
  176. def main():
  177. Charts()
  178. if( __name__ == "__main__" ):
  179. main()