Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions bin/init-category
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

source $(dirname $0)/vars.sh

CATEGORY=$1

if [ -z "${CATEGORY}" ] ; then
echo 'Usage: bin/init-category <category name>'
exit 1
fi

# Populate the initial list
${BIN}/python3 ${DIR}/make-list.py

# No list should have been populated, but if they were, discard
rm ${DIR}/lists/*.txt

# Only inform users of files that were nominated after the bot started running.
# Mark all existing files as handled to achieve that.
echo "UPDATE commons_deletions SET state='notified' WHERE deletion_type='${CATEGORY}';" | mysql --defaults-file=${DIR}/my.cnf

34 changes: 26 additions & 8 deletions commonsbot/formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,11 @@ def format_body(self, files):
return result


class SpeedyFormatter(Formatter):
class PageTagFormatter(Formatter):
"""
Formats messages about speedy deletion nominations
Base class for template-based deletion formatters
"""

def __init__(self, i18n):
"""
@type i18n: commonsbot.i18n.I18n
"""
Formatter.__init__(self, 'speedy', i18n)

def format_body(self, files):
result = self.msg('body-start', len(files)) + '\n'

Expand All @@ -158,3 +152,27 @@ def format_body(self, files):
result += self.msg('body-end', len(files))

return result


class SpeedyFormatter(PageTagFormatter):
"""
Formats messages about speedy deletion nominations
"""

def __init__(self, i18n):
"""
@type i18n: commonsbot.i18n.I18n
"""
Formatter.__init__(self, 'speedy', i18n)


class NoPermissionFormatter(PageTagFormatter):
"""
Formats messages about missing permissions
"""

def __init__(self, i18n):
"""
@type i18n: commonsbot.i18n.I18n
"""
Formatter.__init__(self, 'nopermission', i18n)
11 changes: 11 additions & 0 deletions commonsbot/i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ def language_has_all_messages(code):
return result


class MessageNotFound(Exception):
"""
Exception thrown when a message is not found
"""

def __init__(self, lang_code, message_key):
super.__init__("Language %s misses message '%s'" % (lang_code, message_key))


class I18n(object):
"""
Represents a set of localisation messages in a single language
Expand Down Expand Up @@ -105,6 +114,8 @@ def __init__(self, language):
file.close()

def msg(self, key, params=()):
if key not in self.data:
raise MessageNotFound(self.language, key)
if type(params) != tuple:
params = (params,)
return format(self.data[key], params)
Expand Down
13 changes: 12 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,21 @@
"minoredit": false,
"markasbot": false,
"tags": null,
"language": null
"language": null,
"notification_types": [
"speedy",
"discussion"
]
},
"enwiki": {
"markasbot": false
},
"testwiki": {
"notification_types": [
"speedy",
"discussion",
"nopermission"
]
}
}
}
6 changes: 5 additions & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@
"commtech-commons-discussion-body-end-matching": "Participate in the deletion discussion at the [[$1|nomination page]].",
"commtech-commons-discussion-body-end-mismatching": "Participate in the deletion {{PLURAL:$1|discussions}} at the nomination {{PLURAL:$1|pages}} linked above.",
"commtech-commons-discussion-summary": "Files used on this page are up for deletion",
"commtech-commons-discussion-line": "[[$1]] ([[$2|discussion]])"
"commtech-commons-discussion-line": "[[$1]] ([[$2|discussion]])",
"commtech-commons-nopermission-header": "{{PLURAL:$1|A Commons file|Commons files}} used on this page {{PLURAL:$1|has|have}} is missing permission",
"commtech-commons-nopermission-body-start": "The following Wikimedia Commons {{PLURAL:$1|file|files}} used on this page {{PLURAL:$1|is|are}} missing permission information and may be deleted:",
"commtech-commons-nopermission-body-end": "You can see the details at the file description {{PLURAL:$1|page|pages}} linked above.",
"commtech-commons-nopermission-summary": "Files used on this page are missing permission"
}
6 changes: 5 additions & 1 deletion i18n/qqq.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@
"commtech-commons-discussion-body-end-matching": "Second part of messages left by Community Tech bot on talk pages of articles that have Commons images nominated for deletion. It's used when all pages listed are nominated in the same discussion and is preceded by a list of files and {{msg-intuition|commtech-commons-discussion-body-start}} before it. Parameter:\n* $1 - title of deletion discussion page on Commons",
"commtech-commons-discussion-body-end-mismatching": "Second part of messages left by Community Tech bot on talk pages of articles that have Commons images nominated for deletion. It's used when pages listed are nominated in more than one discussiion and is preceded by a list of files and {{msg-intuition|commtech-commons-discussion-body-start}} before it. Parameter:\n* $1 - number of files nominated for deletion for {{PLURAL}}",
"commtech-commons-discussion-summary": "Edit summary for messages left by Community Tech bot on talk pages of articles that have Commons images nominated for deletion",
"commtech-commons-discussion-line": "Line listing a Commons file nominated for deletion. Parameters:\n* $1 - file name\n* $2 - title of deletion discussion page"
"commtech-commons-discussion-line": "Line listing a Commons file nominated for deletion. Parameters:\n* $1 - file name\n* $2 - title of deletion discussion page",
"commtech-commons-nopermission-header": "Header for messages left by Community Tech bot on talk pages of articles that have Commons images missing permission information. Parameter:\n* $1 - number of files nominated for deletion for {{PLURAL}}",
"commtech-commons-nopermission-body-start": "First part of messages left by Community Tech bot on talk pages of articles that have Commons images missing permission information. It will be followed by a list of files and {{msg-intuition|commtech-commons-nopermission-body-end}}. Parameter:\n* $1 - number of files missing permisssion information for {{PLURAL}}",
"commtech-commons-nopermission-body-end": "Second part of messages left by Community Tech bot on talk pages of articles that have Commons images missing permission information. It's preceded by a list of files and {{msg-intuition|commtech-commons-nopermission-body-start}} before it. Parameter:\n* $1 - number of files missing permisssion information for {{PLURAL}}",
"commtech-commons-nopermission-summary": "Edit summary for messages left by Community Tech bot on talk pages of articles that have Commons images missing permission information"
}
1 change: 1 addition & 0 deletions make-list.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@ def make_list(type, categories, depth, delay):
'Candidates for speedy deletion',
'Copyright violations',
], depth=False, delay=60 * 15)
make_list('nopermission', ['Media missing permission'], depth=1, delay=60 * 60)
23 changes: 16 additions & 7 deletions post-notifs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import sys
from commonsbot import mysql, config
from commonsbot.state import DeletionStateStore, DeletionState
from commonsbot.i18n import I18n, language_has_all_messages
from commonsbot.i18n import I18n, language_has_all_messages, MessageNotFound
from commonsbot.utils import PerWikiMapper, check_already_posted
from commonsbot.formatters import SpeedyFormatter, DiscussionFormatter
from commonsbot.formatters import SpeedyFormatter, DiscussionFormatter, NoPermissionFormatter
import pywikibot
from pywikibot import Site, Page, FilePage
from pywikibot.site import Namespace
Expand Down Expand Up @@ -48,11 +48,15 @@ def spam_notifications(notif_type, formatter_class, talk_page, files):
assert len(files) > 0

wiki_options = config.for_wiki(talk_page.site.dbName())

if notif_type not in wiki_options['notification_types']:
return

lang_code = wiki_options['language']
if lang_code is None:
lang_code = talk_page.site.code
if not language_has_all_messages(lang_code):
return
# if not language_has_all_messages(lang_code):
# return
i18n = I18n.factory(lang_code)

try:
Expand All @@ -73,9 +77,13 @@ def spam_notifications(notif_type, formatter_class, talk_page, files):

ourlist.sort(key=lambda file: file.file_name)

formatter = formatter_class(i18n)
talk_page.text = text + formatter.format(ourlist)
summary = formatter.format_summary()
try:
formatter = formatter_class(i18n)
talk_page.text = text + formatter.format(ourlist)
summary = formatter.format_summary()
except MessageNotFound as e:
print(str(e), file=sys.stderr)
return

if config.dry_run:
print('DRY RUN: not posting about %d %s files to %s' % (len(ourlist), notif_type, talk_page))
Expand Down Expand Up @@ -177,4 +185,5 @@ def save(store):

process_list('discussion', DiscussionFormatter)
process_list('speedy', SpeedyFormatter)
process_list('nopermission', NoPermissionFormatter)
with_store(lambda store: store.expire_failed())
1 change: 1 addition & 0 deletions sql/patch-nopermission.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE commons_deletions MODIFY COLUMN deletion_type ENUM('speedy', 'discussion', 'nopermission');
2 changes: 1 addition & 1 deletion sql/schema.sql
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CREATE TABLE IF NOT EXISTS commons_deletions (
title VARCHAR(255) BINARY NOT NULL,
deletion_type ENUM('speedy', 'discussion') NOT NULL,
deletion_type ENUM('speedy', 'discussion', 'nopermission') NOT NULL,
state ENUM('new', 'notifying', 'failed', 'notified', 'maybe gone', 'gone') NOT NULL DEFAULT 'new',
state_time DATETIME NOT NULL DEFAULT now(),
retries INT NOT NULL DEFAULT 0,
Expand Down