#!/usr/local/bin/perl -w use strict; use warnings; use Data::Dumper; use Carp; #====================================================== # need to convert CC licenses to a list of granted rights. # see data section at end of file in depth description. #====================================================== # A) the right to NOT =A=attribute the author # # R) the right to add license =R=estrictions to derivatives # # the right to copy/distribute the =O=riginal work: # # O1) commercially (excluding advertising) # O2) commercially as advertising # O3) noncommercially # or no rights granted # # the right to copy/distribute =D=erivative works: # # D1) commercially (excluding advertising) # D2) commercially as advertising # D3) noncommercially # or no rights granted #====================================================== # note that the keys (i.e. BY-NC-SA) are in alphabetical order my @AllPossibleLetters = qw (A R O1 O2 O3 D1 D2 D3); my %ConversionTable = ( 'PD' => [qw (A R O1 O2 O3 D1 D2 D3)], 'BY' => [qw ( R O1 O2 O3 D1 D2 D3)], 'SA' => [qw (A O1 O2 O3 D1 D2 D3)], 'BY-SA' => [qw ( O1 O2 O3 D1 D2 D3)], 'NC' => [qw (A R O3 D3)], 'NC-SA' => [qw (A O3 D3)], 'BY-NC' => [qw ( R O3 D3)], 'BY-NC-SA' => [qw ( O3 D3)], 'Sampling+' => [qw (A R O3 D1 D3)], 'NC-Sampling+' => [qw (A R O3 D3)], 'Sampling' => [qw (A R D1 D3)], 'ND' => [qw (A R O1 O2 O3 )], 'BY-ND' => [qw ( R O1 O2 O3 )], ); # print Dumper \%licenses; ######################################################################## # must be at least two licenses on command line. otherwise print help ######################################################################## unless(scalar(@ARGV)>1) { print<<'HELP'; ######################################################################## This script takes in two or more CreativeCommons licenses and determines what the resulting license would be if they can be combined. This might be useful for taking two different works licensed under two different CC licenses and figuring out if you can combine the two in some useful way. To run the script, pass in the CC licenses that you want to combine on the command line when you run the script. cc.pl BY-NC ND A list of currently supported licenses is given here: HELP ; foreach my $key (keys(%ConversionTable)) { print "\t$key\n"; } print<<'HELP'; Copyright 2005 Greg London, All Rights Reserved This module is free software. It may be used, redistributed and/or modified under the terms of the Perl Artistic License (see http://www.perl.com/perl/misc/Artistic.html) http://www.GregLondon.com ######################################################################## HELP ; exit; } print "Copyright 2005 Greg London, All Rights Reserved\n"; print "http://www.GregLondon.com\n"; ######################################################################## # may want to add cleanup to the inputs before processing. ######################################################################## my %translation_table = ( cc=>'cc', pd=>'pd', sa=>'sa', samplingplus=>'samplingplus', sampling=>'sampling', nd=>'nd', creativecommons=>'cc', publicdomain=>'pd', sharealike=>'sa', 'sampling+'=>'samplingplus', noderivatives=>'nd', noderivs=>'nd', nc=>'nc', by=>'by', noncommercial=>'nc', attribution=>'by', ); my @ProcessedCommandLineArguments; foreach my $raw_license (@ARGV) { my $lowercase = lc($raw_license); my @elements = split(/\-/, $lowercase); my @translated_license; foreach my $element (@elements) { unless(exists($translation_table{$element})) { die "Error: unknown element '$element' in license '$raw_license'"; } my $translated_element = $translation_table{$element}; push(@translated_license, $translated_element); } my @sorted_license = sort(@translated_license); my $sorted_string = join("-", @sorted_license); my $uppercase = uc($sorted_string); push(@ProcessedCommandLineArguments, $uppercase); } ######################################################################## # go through all the input licenses and convert them to LUT letters. ######################################################################## my @input_licenses; foreach my $license (@ProcessedCommandLineArguments) { unless(exists($ConversionTable{$license})) { die "Error: don't know nothing about $license"; } my @letter_columns = @{$ConversionTable{$license}}; my %hash = map{$_,1} @letter_columns; push(@input_licenses, \%hash); } # print Dumper \@input_licenses; ######################################################################## # now go through all the licenses and see if they have any letters in common ######################################################################## my %resulting_license; LETTER: foreach my $letter (@AllPossibleLetters) { #warn "testing letter '$letter'"; LICENSE: foreach my $lic_in (@input_licenses) { #print "checking in "; print Dumper $lic_in; unless(exists($lic_in->{$letter})) { next LETTER; } } $resulting_license{$letter}=1; } # print Dumper \%resulting_license; ######################################################################## # now go through the conversion table and find license that fits the # one we just generated. ######################################################################## my %ReversibleTable; while (my($ccname, $arr_ref) = each(%ConversionTable)) { my @array = sort(@$arr_ref); my $arrstr = join("", @array); $ReversibleTable{$arrstr}=$ccname; } my @result_arr = sort(keys(%resulting_license)); my $resulting_key = join("",@result_arr); my $resulting_name = $ReversibleTable{$resulting_key}; # print "resulting_name is '$resulting_name'\n"; ######################################################################## # now check for ShareAlike restrictions. # if any license is share alike, all other licenses must be teh same. ######################################################################## # first generate a list of all the granted rights and how many times granted my %master_list_of_all_granted_rights; foreach my $hash_ref (@input_licenses) { foreach my $letter (keys(%$hash_ref)) { $master_list_of_all_granted_rights{$letter}++; } } # now look to see if "R" was a right granted by any license. # if it wasnt, then someone had a sharealike license, and # counts on all other rights should all be equal unless(exists($master_list_of_all_granted_rights{'R'})) { my $number_of_licenses = scalar(@input_licenses); RIGHT: foreach my $right (keys(%master_list_of_all_granted_rights)) { next RIGHT if(($right eq 'R') or ($right eq 'A')); my $granted_count = $master_list_of_all_granted_rights{$right}; unless($granted_count ==$number_of_licenses) { die "Error: ShareAlike license prohibits this combination"; } } } print "The license of the combined works would be is '$resulting_name'\n"; __DATA__ This script is meant to be used to determine if two or more CreativeCommons licenses can be combined, and if they can be combined, what the resulting license for teh work would be. How to do it: Some CC two-letter-acronyms grant rights and some restrict rights, so you can't just come up with a simple rule without knowing what each acronym means. PD grants rights to downstream folks. BY restricts rights from downstream poeple. The way to programmatically determine license combinations is to rewrite all the two-letter-acronyms in terms of what rights they GRANT to downstream people. Then, license combination becomes extremely simple. You simply take whatever rights are granted by BOTH licenses, and that goes into your combined license. (of course, you have to do a check for sharealike's special conditions, but oh well) Attribution is a restriction. It is not the granting of a right, it is witholding the right for downstream poeple to copy/distribute/derive the original work WITHOUT giving the orignal author credit. But that means you could re-phrase all the licenses that do/do-not have attribution into whether or not the allow poeple to use the work without attributing the original author. So, here are all the rights that can be granted by the author under the various CC licenses: ====================================================== A) the right to NOT =A=attribute the author R) the right to add license =R=estrictions to derivatives the right to copy/distribute the =O=riginal work: O1) commercially (excluding advertising) O2) commercially as advertising O3) noncommercially or no rights granted the right to copy/distribute =D=erivative works: D1) commercially (excluding advertising) D2) commercially as advertising D3) noncommercially or no rights granted ====================================================== just to explain the letter choices: A=Attribution not required R=Restrictions are further allowed O=Original work restrictions D=Derivative work restrictions so: CC-PD = A,R,O1,O2,O3,D1,D2,D3, Note that PD GRANTS all the rights listed above. Now, compare that to the attribution license: CC-BY = ,R,O1,O2,O3,D1,D2,D3, Attribution grants everythign that PD grants EXCEPT "A", the right to NOT credit the author. This approach can be followed with all the licenses: CC-PD = A,R,O1,O2,O3,D1,D2,D3, CC-BY = R,O1,O2,O3,D1,D2,D3, CC-SA = A, ,O1,O2,O3,D1,D2,D3, CC-SA-BY = , ,O1,O2,O3,D1,D2,D3, CC-NC = A,R, , ,O3, , ,D3, CC-NC-BY = ,R, , ,O3, , ,D3, CC-NC-BY-SA = , , , ,O3, , ,D3, CC-Sampling+ = A,R, , ,O3,D1, ,D3, CC-NC-SAMP+ = A,R, , ,O3, , ,D3, CC-Sampling = A,R, , , ,D1, ,D3, CC-ND = A,R,O1,O2,O3, , , , CC-BY-ND = ,R,O1,O2,O3, , , , (I think this table describes all the CC licenses. Did I miss any?) What you then do when you combine licenses is put the two side by side, carry over all the letters that exist in both, and you've got your resulting license. Combining CC-NC with CC-BY gives: CC-BY = R,O1,O2,O3,D1,D2,D3, CC-NC = A,R, , ,O3, , ,D3, ------------------------------------- equals = ,R, , ,O3, , ,D3, and then you look up the resulting license in the table to translate it back to a Creative Commons license. In the above example, the result matches CC-BY-NC This makes it simple enough for a perl script to calculate. The only other check you need to do is check the "R" column so see if the right to put the work under a more Restrictive license has been granted or not. (i.e. if ShareAlike is present) If the "R" right is not present, then the license can only be combine with other licenses that are exactly the same. No fewer rights, no more rights. Hm, with the exception of attribution, which is may not be present in one license but could be combined with a work that does have attribution. You also need to do some checks at the end because you can combine some CC licenses and get a result that does not translate back to a CC license. (cc-Sampling) + (CC-NC-Sampling+) = garbage