Relicense uploads from CC BY-SA 4.0 to CC BY 4.0

I uploaded 54 files via the Wiki Loves Pride 2019 campaign, which pre-selected the CC BY-SA 4.0 license. (I’ve brought this up on the campaign talk page, so this may change in the future.) I generally prefer a more liberal license for my uploads though, without Share-Alike requirement, so I used this PAWS notebook to relicense them.

A bit of Pywikibot setup.

import pywikibot
site = pywikibot.Site("commons", "commons")
import pywikibot.pagegenerators

To experiment with Pywikibot, create a page for the first upload manually. This and the next few steps are based on the create your own script manual.

page = pywikibot.Page(site, 'File:CSD Berlin 2019 - Lucas Werkmeister - 01.jpg')

Use a simple string replace to change the license…

page.text = page.text.replace('{{self|cc-by-sa-4.0}}', '{{self|cc-by-4.0}}')

…and save the change as a new revision, using a good edit summary.

page.save('relicense from [[Template:cc-by-sa-4.0|CC BY-SA 4.0]] to [[Template:cc-by-4.0|CC BY 4.0]], remove ShareAlike requirement')
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 01.jpg]] saved

Create a function to do the same to other pages (but only try to save them if there’s actually a change).

def relicense(page):
    text = page.text.replace('{{self|cc-by-sa-4.0}}', '{{self|cc-by-4.0}}')
    if text != page.text:
        page.text = text
        page.save('relicense from [[Template:cc-by-sa-4.0|CC BY-SA 4.0]] to [[Template:cc-by-4.0|CC BY 4.0]], remove ShareAlike requirement')

Now, I want to call this function with all of my uploads for this campaign. I found the UserContributionsGenerator in the pagegenerators documentation – it doesn’t have a lot of filter options (“all my uploads from 2019-07-28” would have been ideal), but since I didn’t have any more recent contributions in the file namespace, it was enough to go through all my contributions there and stop as soon as a file didn’t match the pattern of my uploads anymore.

NS_FILE = 6
for page in pywikibot.pagegenerators.UserContributionsGenerator('Lucas Werkmeister', namespaces=[NS_FILE], site=site):
    if not page.title().startswith('File:CSD Berlin 2019 - Lucas Werkmeister -'):
        break
    print(page.title())
File:CSD Berlin 2019 - Lucas Werkmeister - 01.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 53 - Leather Pride flag.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 51 - Signs.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 54 - EU Rainbow.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 52 - Signs.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 24 - Bi, Pan, Ace Flags.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 21 - Giant Bi Flag.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 45 - Bi, Enby Flags.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 41 - Greens.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 40 - Greens.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 50 - Signs.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 30 - PACE.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 49 - Signs.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 39 - Railbow.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 17 - Drag Queens.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 36.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 23 - Giant Bi Flag.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 05 - Asexual Pride.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 22 - Giant Bi Flag.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 48 - Auswärtiges Amt.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 47 - Auswärtiges Amt.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 46 - Mozilla.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 44 - Amnesty International.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 43 - Amnesty International.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 42 - Amnesty International.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 38.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 37 - BVG.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 35.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 34 - Russian.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 32 - EIS.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 33 – Pride Is A Protest.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 31 - Different People.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 29 – DGB.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 28 - Celebrate Marriage Equality In Taiwan.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 27 - US Mission Germany.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 26 - US Mission Germany.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 25 - US Mission Germany.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 20 - Querplattler.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 19 - Querplattler.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 18 - Querplattler.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 16 - Country Pride Flags.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 15 - Country Pride Flags.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 13 - Megan And The Rapinoes.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 14 - Megan And The Rapinoes.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 12 - Megan And The Rapinoes.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 11 - Megan And The Rapinoes.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 10 - Musicians.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 09 - Sex Work Is Work and L With The T.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 08 - Climate Justice Without Border.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 07 - Queers For Future.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 06.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 04 - Love Has No Gender.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 02.jpg
File:CSD Berlin 2019 - Lucas Werkmeister - 03 - Love Has No Gender.jpg

The list of printed titles looks fine and has the right number of lines (54), so let’s actually call relicense() now. (The duplicated NS_FILE definition is unnecessary, I just forgot to remove it when I copy+pasted the cell contents.)

NS_FILE = 6
for page in pywikibot.pagegenerators.UserContributionsGenerator('Lucas Werkmeister', namespaces=[NS_FILE], site=site):
    if not page.title().startswith('File:CSD Berlin 2019 - Lucas Werkmeister -'):
        break
    relicense(page)
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 53 - Leather Pride flag.jpg]] saved
Sleeping for 9.1 seconds, 2019-07-28 17:02:01
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 51 - Signs.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:02:11
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 54 - EU Rainbow.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:02:21
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 52 - Signs.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:02:31
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 24 - Bi, Pan, Ace Flags.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:02:41
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 21 - Giant Bi Flag.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:02:51
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 45 - Bi, Enby Flags.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:03:01
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 41 - Greens.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:03:11
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 40 - Greens.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:03:21
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 50 - Signs.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:03:31
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 30 - PACE.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:03:41
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 49 - Signs.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:03:51
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 39 - Railbow.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:04:01
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 17 - Drag Queens.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:04:11
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 36.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:04:21
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 23 - Giant Bi Flag.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:04:31
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 05 - Asexual Pride.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:04:41
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 22 - Giant Bi Flag.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:04:51
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 48 - Auswärtiges Amt.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:05:01
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 47 - Auswärtiges Amt.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:05:11
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 46 - Mozilla.jpg]] saved
Sleeping for 9.0 seconds, 2019-07-28 17:05:21
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 44 - Amnesty International.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:05:31
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 43 - Amnesty International.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:05:41
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 42 - Amnesty International.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:05:51
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 38.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:06:01
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 37 - BVG.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:06:11
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 35.jpg]] saved
Sleeping for 9.1 seconds, 2019-07-28 17:06:21
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 34 - Russian.jpg]] saved
Sleeping for 9.1 seconds, 2019-07-28 17:06:31
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 32 - EIS.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:06:41
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 33 – Pride Is A Protest.jpg]] saved
Sleeping for 8.1 seconds, 2019-07-28 17:06:52
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 31 - Different People.jpg]] saved
Sleeping for 9.0 seconds, 2019-07-28 17:07:01
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 29 – DGB.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:07:11
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 28 - Celebrate Marriage Equality In Taiwan.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:07:21
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 27 - US Mission Germany.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:07:31
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 26 - US Mission Germany.jpg]] saved
Sleeping for 9.0 seconds, 2019-07-28 17:07:41
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 25 - US Mission Germany.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:07:51
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 20 - Querplattler.jpg]] saved
Sleeping for 9.4 seconds, 2019-07-28 17:08:01
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 19 - Querplattler.jpg]] saved
Sleeping for 9.1 seconds, 2019-07-28 17:08:11
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 18 - Querplattler.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:08:21
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 16 - Country Pride Flags.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:08:31
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 15 - Country Pride Flags.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:08:41
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 13 - Megan And The Rapinoes.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:08:51
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 14 - Megan And The Rapinoes.jpg]] saved
Sleeping for 9.1 seconds, 2019-07-28 17:09:01
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 12 - Megan And The Rapinoes.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:09:11
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 11 - Megan And The Rapinoes.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:09:21
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 10 - Musicians.jpg]] saved
Sleeping for 9.0 seconds, 2019-07-28 17:09:31
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 09 - Sex Work Is Work and L With The T.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:09:41
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 08 - Climate Justice Without Border.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:09:51
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 07 - Queers For Future.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:10:01
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 06.jpg]] saved
Sleeping for 9.3 seconds, 2019-07-28 17:10:11
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 04 - Love Has No Gender.jpg]] saved
Sleeping for 9.1 seconds, 2019-07-28 17:10:21
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 02.jpg]] saved
Sleeping for 9.2 seconds, 2019-07-28 17:10:31
Page [[commons:File:CSD Berlin 2019 - Lucas Werkmeister - 03 - Love Has No Gender.jpg]] saved

Done! :)