ವಿಕಿಸೋರ್ಸ್:ವಿಕಿಸೋರ್ಸ್೨೦/ಅಂಕೆಗಳು
ಗೋಚರ
| ಸಂ. | ಸದಸ್ಯ/ಸದಸ್ಯೆ | ಮುಖ್ಯ | ಕರ್ತೃ | ಪುಟ(points) | ಪರಿವಿಡಿ | ಅನುವಾದ | ಪುಟ ಸೃಷ್ಟಿ (1 ಅಂಕ ಒಂದು ಪುಟ ಸಂಪಾದನೆಗೆ) |
ಪ್ರೂಫ್ ರೀಡ್ (2 ಅಂಕ ಒಂದು ಪುಟ ಸಂಪಾದನೆಗೆ) |
ವ್ಯಾಲಿಡೇಶನ್ (3 ಅಂಕ ಒಂದು ಪುಟ ಸಂಪಾದನೆಗೆ) |
ಒಟ್ಟು ಸಂಪಾದನೆಗಳು | ಒಟ್ಟು ಅಂಕಗಳು |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Shreelatha.Halemane | 0 | 0 | 7836 (12401) | 0 | 0 | 4890 | 881 (1762) | 1956 (5868) | 8265 | 12401 |
| 2 | Pragathi. BH | 0 | 0 | 9511 (11568) | 0 | 0 | 7987 | 163 (326) | 1309 (3927) | 10238 | 11568 |
| 3 | Shreesha Sharma | 0 | 0 | 3817 (5570) | 0 | 0 | 2097 | 808 (1616) | 503 (1509) | 4362 | 5570 |
| 4 | Sharanya K H | 0 | 0 | 3832 (3992) | 0 | 0 | 3626 | 210 (420) | 5 (15) | 3966 | 3992 |
| 5 | Ashwini Rai K | 0 | 0 | 539 (1278) | 0 | 0 | 70 | 64 (128) | 400 (1200) | 670 | 1278 |
| 6 | Adhya.B | 0 | 0 | 578 (594) | 0 | 0 | 553 | 22 (44) | 1 (3) | 605 | 594 |
| 7 | Vikashegde | 0 | 0 | 252 (498) | 13 | 0 | 0 | 130 (260) | 95 (285) | 343 | 506 |
| 8 | A826 | 10740 | 1 | 214 (272) | 28 | 0 | 6 | 9 (18) | 34 (102) | 11010 | 298 |
| 9 | Hariprasad Shetty10 | 0 | 0 | 107 (224) | 0 | 0 | 0 | 36 (72) | 48 (144) | 448 | 224 |
| 10 | Athmi.J | 0 | 0 | 221 (221) | 0 | 0 | 221 | 0 (0) | 0 (0) | 221 | 221 |
| 11 | Vinoda mamatharai | 0 | 0 | 140 (170) | 0 | 0 | 79 | 36 (72) | 5 (15) | 168 | 170 |
| 12 | Anzx-ooo | 2 | 0 | 70 (152) | 1 | 0 | 0 | 8 (16) | 49 (147) | 105 | 155 |
| 13 | ~2026-24108-44 | 0 | 0 | 44 (44) | 0 | 0 | 44 | 0 (0) | 0 (0) | 44 | 44 |
| 14 | Babitha Shetty | 0 | 0 | 16 (31) | 0 | 0 | 0 | 7 (14) | 5 (15) | 39 | 31 |
| 15 | Viveka BG | 0 | 0 | 6 (12) | 0 | 0 | 0 | 6 (12) | 0 (0) | 12 | 12 |
| 16 | Shyam 2808 | 0 | 0 | 6 (10) | 0 | 0 | 0 | 6 (12) | 0 (0) | 9 | 10 |
| 17 | Vikas shetty14 | 0 | 0 | 6 (9) | 0 | 0 | 0 | 6 (12) | 0 (0) | 14 | 9 |
| 18 | ~2026-25228-62 | 0 | 0 | 7 (7) | 0 | 0 | 7 | 0 (0) | 0 (0) | 7 | 7 |
| 19 | Reema Jalihal | 0 | 0 | 6 (7) | 0 | 0 | 0 | 6 (12) | 0 (0) | 26 | 7 |
| 20 | Nihar Chakravarti | 0 | 0 | 6 (6) | 0 | 0 | 0 | 6 (12) | 0 (0) | 13 | 6 |
| 21 | ~2026-25211-05 | 0 | 0 | 4 (4) | 0 | 0 | 4 | 0 (0) | 0 (0) | 4 | 4 |
| 22 | VASANTH S.N. | 0 | 0 | 3 (3) | 0 | 0 | 0 | 1 (2) | 0 (0) | 5 | 3 |
| 23 | ~2026-31610-21 | 0 | 0 | 1 (3) | 0 | 0 | 0 | 0 (0) | 1 (3) | 1 | 3 |
| 24 | ChiK | 0 | 0 | 0 (0) | 1 | 0 | 0 | 0 (0) | 0 (0) | 1 | 1 |
| 25 | ~2026-24744-13 | 2 | 0 | 0 (0) | 0 | 0 | 0 | 0 (0) | 0 (0) | 2 | 1 |
| 26 | ~2026-25977-16 | 1 | 0 | 0 (0) | 0 | 0 | 0 | 0 (0) | 0 (0) | 1 | 1 |
| 27 | ~2026-25629-17 | 0 | 0 | 1 (1) | 0 | 0 | 0 | 0 (0) | 0 (0) | 2 | 1 |
| 28 | ~2026-25495-03 | 0 | 0 | 1 (1) | 0 | 0 | 1 | 0 (0) | 0 (0) | 1 | 1 |
| 29 | ~2026-24828-68 | 0 | 0 | 1 (1) | 0 | 0 | 1 | 0 (0) | 0 (0) | 1 | 1 |
| 30 | ~2026-24264-88 | 0 | 0 | 1 (1) | 0 | 0 | 1 | 0 (0) | 0 (0) | 1 | 1 |
| 31 | ~2026-24211-03 | 0 | 0 | 1 (1) | 0 | 0 | 0 | 0 (0) | 0 (0) | 1 | 1 |
| 32 | ~2026-24009-50 | 0 | 0 | 1 (1) | 0 | 0 | 1 | 0 (0) | 0 (0) | 1 | 1 |
| 33 | ~2026-32030-28 | 0 | 0 | 1 (1) | 0 | 0 | 0 | 0 (0) | 0 (0) | 1 | 1 |
#!/usr/bin/env python3
import requests
import time
from datetime import datetime, timezone, timedelta
from collections import defaultdict
import re
START_DATE = datetime(2026, 4, 18, 18, 0, 1, tzinfo=timezone.utc)
END_DATE = datetime(2026, 6, 3, 23, 59, 59, tzinfo=timezone.utc)
TARGET_NAMESPACES = [0, 102, 104, 106, 114]
NAMESPACE_NAMES = {
0: "ಮುಖ್ಯ",
102: "ಕರ್ತೃ",
104: "ಪುಟ",
106: "ಪರಿವಿಡಿ",
114: "ಅನುವಾದ"
}
# Scoring rules for namespace 104
SCORING_RULES = {
'page_creation': 1, # New page creation
'proofread': 2, # Edit summary contains "/* Proofread */"
'validation': 3, # Edit summary contains "/* Validated */"
'regular_edit': 1 # Regular edit in namespace 104
}
WIKI_URL = "https://kn.wikisource.org/w/api.php"
DATA_GENERATION_TIME = datetime.now(timezone.utc)
# Convert to IST for display
IST = timezone(timedelta(hours=5, minutes=30))
DATA_GENERATION_TIME_IST = DATA_GENERATION_TIME.astimezone(IST)
START_DATE_IST = START_DATE.astimezone(IST)
END_DATE_IST = END_DATE.astimezone(IST)
# User to exclude from namespace 0 (set their points to zero)
EXCLUDED_USER = "A826"
EXCLUDED_NAMESPACE = 0
def get_namespace_name(ns):
return NAMESPACE_NAMES.get(ns, f"Namespace {ns}")
def fetch_all_edits():
user_namespace_stats = defaultdict(lambda: defaultdict(set)) # Track unique pages per namespace for scoring
user_scores = defaultdict(lambda: defaultdict(int)) # Track scores by user and namespace
user_edit_details = defaultdict(list) # Store edit details for debugging
user_total_edits = defaultdict(int) # Track total number of edits per user (including duplicates)
user_namespace_edit_counts = defaultdict(lambda: defaultdict(int)) # Track total edit counts per namespace
# Track specific edit types in namespace 104
user_ns104_stats = defaultdict(lambda: {
'creations': 0,
'proofreads': 0,
'validations': 0,
'regular': 0,
'proofread_score': 0, # Track proofread score separately
'validation_score': 0 # Track validation score separately
})
start_iso = START_DATE.strftime('%Y-%m-%dT%H:%M:%SZ')
end_iso = END_DATE.strftime('%Y-%m-%dT%H:%M:%SZ')
print("=" * 80)
print("KANNADA WIKISOURCE EDIT SCORING TOOL")
print("=" * 80)
print(f"Start (UTC): {START_DATE.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Start (IST): {START_DATE_IST.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"End (UTC): {END_DATE.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"End (IST): {END_DATE_IST.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Generated (UTC): {DATA_GENERATION_TIME.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Generated (IST): {DATA_GENERATION_TIME_IST.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Namespaces: {', '.join([f'{get_namespace_name(ns)} ({ns})' for ns in TARGET_NAMESPACES])}")
print(f"User '{EXCLUDED_USER}' gets 0 points in namespace {EXCLUDED_NAMESPACE} ({get_namespace_name(EXCLUDED_NAMESPACE)})")
print(f"Scoring in namespace 104 (ಪುಟ):")
print(f" - Page creation: {SCORING_RULES['page_creation']} point")
print(f" - Proofread (/* Proofread */): {SCORING_RULES['proofread']} points")
print(f" - Validation (/* Validated */): {SCORING_RULES['validation']} points")
print(f" - Regular edit: {SCORING_RULES['regular_edit']} point")
print("-" * 80)
params = {
'action': 'query',
'list': 'recentchanges',
'rcstart': end_iso,
'rcend': start_iso,
'rcnamespace': '|'.join(str(ns) for ns in TARGET_NAMESPACES),
'rcprop': 'title|user|timestamp|ids|comment|flags',
'rctype': 'edit|new',
'rclimit': '500',
'format': 'json'
}
total_edits = 0
excluded_edits = 0
continue_token = None
page_count = 0
while True:
if continue_token:
params['rccontinue'] = continue_token
try:
response = requests.get(WIKI_URL, params=params, timeout=30)
data = response.json()
if 'query' not in data or 'recentchanges' not in data['query']:
break
changes = data['query']['recentchanges']
page_count += 1
print(f"Batch {page_count}... ({len(changes)} edits)")
for change in changes:
user = change.get('user', 'Unknown')
title = change.get('title', '')
ns = change.get('ns', 0)
comment = change.get('comment', '')
is_new = change.get('type') == 'new'
# Increment total edit count for this user (every edit counts)
user_total_edits[user] += 1
total_edits += 1
user_namespace_edit_counts[user][ns] += 1
# Set points to zero for A826 in namespace 0
if ns == EXCLUDED_NAMESPACE and user == EXCLUDED_USER:
score = 0
# Track unique page for scoring purposes (still counts as 0 points)
if title not in user_namespace_stats[user][ns]:
user_namespace_stats[user][ns].add(title)
user_scores[user][ns] += score
excluded_edits += 1
continue
if ns in TARGET_NAMESPACES:
# Calculate score for this edit
score = 0
if ns == 104: # Special scoring for namespace 104
if is_new:
# Page creation
score = SCORING_RULES['page_creation']
user_ns104_stats[user]['creations'] += 1
user_edit_details[user].append(f"Created page: {title} (+{score})")
elif '/* Validated */' in comment:
# Validation edit
score = SCORING_RULES['validation']
user_ns104_stats[user]['validations'] += 1
user_ns104_stats[user]['validation_score'] += score
user_edit_details[user].append(f"Validated: {title} (+{score})")
elif '/* Proofread */' in comment:
# Proofread edit
score = SCORING_RULES['proofread']
user_ns104_stats[user]['proofreads'] += 1
user_ns104_stats[user]['proofread_score'] += score
user_edit_details[user].append(f"Proofread: {title} (+{score})")
else:
# Regular edit
score = SCORING_RULES['regular_edit']
user_ns104_stats[user]['regular'] += 1
user_edit_details[user].append(f"Regular edit: {title} (+{score})")
else:
# For other namespaces, count each unique page as 1 point
score = 1
# Track unique pages per namespace for scoring
if title not in user_namespace_stats[user][ns]:
user_namespace_stats[user][ns].add(title)
user_scores[user][ns] += score
if total_edits % 500 == 0:
print(f" Processed {total_edits} edits...")
if 'continue' in data and 'rccontinue' in data['continue']:
continue_token = data['continue']['rccontinue']
time.sleep(0.5)
else:
print("Finished fetching all edits!")
break
except Exception as e:
print(f"Error: {e}")
break
print("-" * 80)
print(f"Batches: {page_count}")
print(f"Total edits fetched: {total_edits}")
print(f"User '{EXCLUDED_USER}' edits in namespace {EXCLUDED_NAMESPACE} (scored 0): {excluded_edits}")
print(f"Users with edits: {len(user_total_edits)}")
# Summary of total edits per user
print("\nTotal edits per user (including duplicates):")
print("-" * 60)
for user in sorted(user_total_edits.items(), key=lambda x: x[1], reverse=True)[:20]:
print(f" {user[0]}: {user[1]} edits")
print("=" * 80)
return (user_namespace_stats, user_scores, user_ns104_stats,
user_total_edits, total_edits, user_namespace_edit_counts)
def generate_wikitable(user_namespace_stats, user_scores, user_ns104_stats,
user_total_edits, total_competition_edits, user_namespace_edit_counts):
table_data = []
for user in user_total_edits.keys():
# Calculate total points (sum of scores from all namespaces)
total_points = sum(user_scores[user].values())
# Get unique page counts per namespace
ns_unique_pages = {}
for ns in TARGET_NAMESPACES:
ns_pages = user_namespace_stats[user].get(ns, set())
ns_unique_pages[ns] = len(ns_pages)
# Get total edit counts per namespace (including duplicates)
ns_total_edits = user_namespace_edit_counts.get(user, {})
# Get namespace 104 detailed stats
ns104_stats = user_ns104_stats.get(user, {
'creations': 0,
'proofreads': 0,
'validations': 0,
'regular': 0,
'proofread_score': 0,
'validation_score': 0
})
table_data.append({
'user': user,
'total_score': total_points,
'total_edits': user_total_edits.get(user, 0),
'ns0_edits': ns_total_edits.get(0, 0), # Show total edits, not unique pages
'ns102_edits': ns_total_edits.get(102, 0),
'ns104_unique': ns_unique_pages.get(104, 0),
'ns104_score': user_scores[user].get(104, 0),
'ns106_edits': ns_total_edits.get(106, 0),
'ns114_edits': ns_total_edits.get(114, 0),
'creations': ns104_stats['creations'],
'proofreads': ns104_stats['proofreads'],
'proofread_score': ns104_stats['proofread_score'],
'validations': ns104_stats['validations'],
'validation_score': ns104_stats['validation_score']
})
table_data = [row for row in table_data if row['total_score'] > 0 or row['total_edits'] > 0]
table_data.sort(key=lambda x: x['total_score'], reverse=True)
if not table_data:
return "No edits found in the specified date range."
wikitable = []
wikitable.append('{| class="wikitable sortable" style="text-align:center; width:100%; font-size:75%; color: blue;"')
wikitable.append(f'|+ ಕನ್ನಡ ವಿಕಿಸೋರ್ಸ್ ಸಂಪಾದನಾ ಸ್ಕೋರ್ಗಳು - ಒಟ್ಟು ಸ್ಪರ್ಧೆಯ ಸಂಪಾದನೆಗಳು: {total_competition_edits}<br><small>ದತ್ತಾಂಶ ಪಡೆದ ಸಮಯ: {DATA_GENERATION_TIME.strftime("%Y-%m-%d %H:%M:%S")} UTC / {DATA_GENERATION_TIME_IST.strftime("%Y-%m-%d %H:%M:%S")} IST</small>')
# Updated header with combined columns for proofread and validation
header_cols = ['! ಸಂ.', '!! ಸದಸ್ಯ/ಸದಸ್ಯೆ', '!! ಮುಖ್ಯ', '!! ಕರ್ತೃ', '!! ಪುಟ(points)', '!! ಪರಿವಿಡಿ', '!! ಅನುವಾದ', '!! ಪುಟ ಸೃಷ್ಟಿ', '!! ಪ್ರೂಫ್ ರೀಡ್ (ಅಂಕ)', '!! ವ್ಯಾಲಿಡೇಶನ್ (ಅಂಕ)', '!! ಒಟ್ಟು ಸಂಪಾದನೆಗಳು', '!! ಒಟ್ಟು ಅಂಕಗಳು']
wikitable.append(' '.join(header_cols))
for idx, row in enumerate(table_data, start=1):
user = row['user']
# Always use Special:Contributions link
user_link = f"[[Special:Contributions/{user}|{user}]]"
# Show both unique page count and weighted score for namespace 104
ns104_display = f"{row['ns104_unique']} ({row['ns104_score']})"
# Combine proofread count and score into one column
proofread_display = f"{row['proofreads']} ({row['proofread_score']})"
# Combine validation count and score into one column
validation_display = f"{row['validations']} ({row['validation_score']})"
wikitable.append(f"|-\n| {idx} || {user_link} || {row['ns0_edits']} || {row['ns102_edits']} || {ns104_display} || {row['ns106_edits']} || {row['ns114_edits']} || {row['creations']} || {proofread_display} || {validation_display} || {row['total_edits']} || '''{row['total_score']}'''")
wikitable.append('|}')
return '\n'.join(wikitable)
def main():
(user_namespace_stats, user_scores, user_ns104_stats,
user_total_edits, total_competition_edits, user_namespace_edit_counts) = fetch_all_edits()
if not user_total_edits:
print("\nNo data retrieved.")
return
output = generate_wikitable(user_namespace_stats, user_scores, user_ns104_stats,
user_total_edits, total_competition_edits, user_namespace_edit_counts)
print("\n" + "=" * 80)
print("WIKITABLE OUTPUT (Copy this entire section):")
print("=" * 80)
print(output)
print("=" * 80)
if __name__ == "__main__":
main()