<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wiki.creativecommons.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=HSAENZL</id>
		<title>Creative Commons - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.creativecommons.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=HSAENZL"/>
		<link rel="alternate" type="text/html" href="https://wiki.creativecommons.org/wiki/Special:Contributions/HSAENZL"/>
		<updated>2026-04-17T02:55:26Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>https://wiki.creativecommons.org/index.php?title=Liblicense_tutorial&amp;diff=8342</id>
		<title>Liblicense tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.creativecommons.org/index.php?title=Liblicense_tutorial&amp;diff=8342"/>
				<updated>2007-08-09T16:49:46Z</updated>
		
		<summary type="html">&lt;p&gt;HSAENZL: /* Command-line Interface */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Python and GTK ==&lt;br /&gt;
With the release of liblicense (ll) 0.3 we've introduced the beginnings of desktop integration. With this brief guide I hope to drive further integration into other apps. While I'll be using the python bindings for simplicity, the C bindings are very similar. In this section I will show how the integration through nautilus-python is done. Here is a screenshot from nautilus.&lt;br /&gt;
&lt;br /&gt;
[[Image:ll_nautilus_emblem.png]]&lt;br /&gt;
&lt;br /&gt;
The first step of writing any plugin is figuring out the relevant APIs. In this case, the relevant APIs are that of liblicense and nautilus-python. The former's API is familiar to me because I wrote it but for consistencies sake the documentation is on the wiki. The nautilus-python documentation is pretty sparse as is the nautilus extension C documentation. However, I found this documentation file on the gnome svn. There are two primary integrations which I'll talk about. The first is the license emblem shown in the screenshot above. The second is a license properties tab. We'll start with the emblem because it uses the read function of liblicense.&lt;br /&gt;
&lt;br /&gt;
First off to have nautilus load the plugin we place the python file in either /usr/lib/nautilus/extensions-1.0/python or ~/.nautilus/python-extensions/. Our name for the file is nautilus-liblicense.py. We'll put both aspects of the integration in this file. Next we'll import the necessary modules.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;import liblicense&lt;br /&gt;
import urllib&lt;br /&gt;
&lt;br /&gt;
import gtk&lt;br /&gt;
import nautilus&lt;br /&gt;
from liblicense.gui_gtk import *&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Urllib is used to replace things such as %20 (for space) with their correct character. Gtk can be ignored for now as we'll see it in the second part. The nautilus import provides the classes which we'll subclass to provide the desired functionality. Lastly, the two liblicense imports provide us with the library functions and the gtk selector widget which we'll use later.&lt;br /&gt;
&lt;br /&gt;
In order to process the files upon load we'll subclass the InfoProvider class from nautilus-python (imported as nautilus). Within this class we need to override one function, update_file_info, which takes on argument, a FileInfo object, in addition to self.&lt;br /&gt;
&lt;br /&gt;
The class so far:&lt;br /&gt;
&amp;lt;pre&amp;gt;class LicenseInfoProvider(nautilus.InfoProvider):&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        pass&lt;br /&gt;
    def update_file_info(self, f):&lt;br /&gt;
        pass&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is nothing we need to do upon init but we'll leave it there.  In a nautilus-python example they did similar.  So now in the update_file_info function we'll need to read the license of the file and assign a corresponding emblem.  Currently, two emblems are used, one for Creative Commons licenses and another for anything else.  Here is this final code of the update_file_info function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def update_file_info(self, f):&lt;br /&gt;
        if f.get_uri()[:7]==&amp;quot;file://&amp;quot;:&lt;br /&gt;
            license = liblicense.read(urllib.unquote(f.get_uri()[7:]))&lt;br /&gt;
            if license:&lt;br /&gt;
                if &amp;quot;Creative Commons&amp;quot; in liblicense.get_attribute(license,&amp;quot;http://purl.org/dc/elements/1.1/creator&amp;quot;,False):&lt;br /&gt;
                    f.add_emblem(&amp;quot;cc&amp;quot;)&lt;br /&gt;
                else:&lt;br /&gt;
                    f.add_emblem(&amp;quot;licensed&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first check that is done makes sure that the argument is a local file by check that it begins with &amp;quot;file://&amp;quot;.  Once that is confirmed, we then read the license of the file by calling liblicense.'''read'''(''filename'').  Here urllib is used to convert url encoded characters, such as %20 for a space, so that we have an accurate file path.  This is all done on everything after the first seven characters of the uri which '''get_uri'''() returned.&lt;br /&gt;
&lt;br /&gt;
After the license is read we check that it is not null.  If its not then we use liblicense.'''get_attribute''' to get the creator of the license to check if it is Creative Commons or not.  We use python's keyword '''in''' because '''get_attribute''' returns a list of values.  The arguments for '''get_attribute''' are the license uri, the desired attributes uri (the predicate in RDF terms) and finally a boolean toggling the locale awareness of the processing.  Once all of this is done we add the corresponding emblem using the FileInfo object's '''add_emblem''' function which takes the emblem keyword.  Upon install of liblicense these two icons are added.  The keyword is taken from the filename (emblem-''keyword''.{png,svg}) not the .icon file.  That explains all of the first part.  If you have further questions visit #cc on irc.freenode.net or email cc-devel@lists.ibiblio.org.&lt;br /&gt;
&lt;br /&gt;
The second part of this section and of the nautilus liblicense integration is the properties tab.  Through this tab one can see the exact license the file is currently under and they can also modify the license.  This is done by utilizing the packaged LicenseChooser liblicense gtk widget.  Lets have a look.&lt;br /&gt;
&lt;br /&gt;
First lets set up the nautilus API for a property page:&lt;br /&gt;
&amp;lt;pre&amp;gt;class LicensePropertyPage(nautilus.PropertyPageProvider):&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    def get_property_pages(self, files):&lt;br /&gt;
        pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, similar to the first section we're subclassing a nautilus class.  And again, we need to subclass one function.  This time we need to subclass the '''get_property_pages''' method.  This method takes in a list of '''FileInfo''' objects and returns a sequence of '''PropertyPage'''s.&lt;br /&gt;
&lt;br /&gt;
Alright, lets get started.  While the first iteration of this integration only supported a single file, we'll jump straight to the multiple file version.&lt;br /&gt;
&amp;lt;pre&amp;gt;def get_property_pages(self, files):&lt;br /&gt;
        self.files = files&lt;br /&gt;
&lt;br /&gt;
        self.files = filter(lambda f: f.get_uri_scheme() == 'file' and not f.is_directory(),self.files)&lt;br /&gt;
        self.files = map(lambda f: urllib.unquote(f.get_uri()[7:]),self.files)&lt;br /&gt;
        &lt;br /&gt;
        if len(self.files)==0:&lt;br /&gt;
            return&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In this first bit we do some python wizardry.  First we store the files list in the object itself, we'll need it later.  Now we '''filter''' out the files with a different uri scheme and those which are directories.  This leaves us with a list of '''FileInfo''' objects which have uris in the &amp;quot;file:///path/filename.ext&amp;quot; form.  So to get a list of files in the liblicense form we use '''map''' and '''urllib.unquote''' like we did in the previous part.  Finally, before we continue, we make sure we have not filtered out all of the selected items.&lt;br /&gt;
&lt;br /&gt;
Now that we have a list of relevant files we need to do one of two things, if there is only one file selected we start the license chooser displaying the appropriate license or we display no license if multiple files are selected.  '''get_property_pages''' continued:&lt;br /&gt;
&amp;lt;pre&amp;gt;self.property_label = gtk.Label('License')&lt;br /&gt;
        self.property_label.show()&lt;br /&gt;
        &lt;br /&gt;
        if len(files) == 1:&lt;br /&gt;
            license = liblicense.read(self.files[0])&lt;br /&gt;
            if license==None:&lt;br /&gt;
                license = liblicense.get_default()&lt;br /&gt;
        else:&lt;br /&gt;
            license = None&lt;br /&gt;
        self.box = LicenseWidget(license)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
First, we create the label for the property tab.  After this we see how many files we are dealing with.  If its one, we call read on the first and only element of the list and proceed to check whether it exists (in other words, is ''None'' or not).  When the license is ''None'' we default to the system default license.  If there is multiple files we simply set the license to ''None''.  Finally, we create the '''LicenseWidget''' (which is a subclass of '''gtk.HBox''') passing the desired starting license uri in.&lt;br /&gt;
&lt;br /&gt;
The last task we must complete is to write the license to the selected file(s) when the properties window is closed.  To do this we attach a callback to the destroy signal of the '''LicenseWidget'''.&lt;br /&gt;
&amp;lt;pre&amp;gt;        self.box.connect(&amp;quot;destroy&amp;quot;,self.license_chosen)&lt;br /&gt;
        self.box.show()&lt;br /&gt;
        &lt;br /&gt;
        return nautilus.PropertyPage(&amp;quot;NautilusPython::license&amp;quot;,&lt;br /&gt;
                                     self.property_label, self.box),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above should be self explanatory.  We simply use the PyGTK widget method '''connect''' to attach a method to the signal.  Then we return a sequence (note the ending comma) of '''PropertyPage'''s created in the return statement.  I copied this from the nautilus-python example and assume the arguments are an identifier, a label and a widget to be packed in the tab.&lt;br /&gt;
&lt;br /&gt;
Lastly, the callback method is pretty simple.&lt;br /&gt;
&amp;lt;pre&amp;gt;    def license_chosen(self, widget):&lt;br /&gt;
        license = self.box.get_license()&lt;br /&gt;
        if license:&lt;br /&gt;
            for f in self.files:&lt;br /&gt;
                liblicense.write(f,license)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Like all GTK callbacks the first argument is the widget which emitted the signal along with self.  Upon receiving this signal we get the current license of the widget by calling the '''LicenseWidget''''s get_license method which returns the uri for the selected license or ''None'' if no license is selected.  Then we check to see if a license was selected and if so iterate through the selected files writing the license info to each one.  This writing is done using the liblicense '''write''' method which takes the file path and the license uri.  It utilizes liblicense modules which write to a variety of different file formats.&lt;br /&gt;
&lt;br /&gt;
Well, thats the end of the liblicense nautilus integration.  The entire file can be seen at [http://cctools.svn.sourceforge.net/viewvc/cctools/liblicense/trunk/src/gnome/nautilus-liblicense.py?revision=6398&amp;amp;view=markup  Liblicense svn browse].&lt;br /&gt;
&lt;br /&gt;
--[[User:Scott Shawcroft|Scott Shawcroft]] 17:03, 29 July 2007 (EDT)&lt;br /&gt;
&lt;br /&gt;
== License Chooser ==&lt;br /&gt;
&lt;br /&gt;
Liblicense aims to make integration of license selection into applications seamless.  The license chooser API allows for selecting licenses based on what the license permits, requires, and/or prohibits.  For example, the license chooser API makes an excellent backend to the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Kde_properties.png]]&lt;br /&gt;
&lt;br /&gt;
=== Graphical License Chooser ===&lt;br /&gt;
&lt;br /&gt;
I'll start with a simple example that uses the Python bindings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from liblicense import LicenseChooser&lt;br /&gt;
&lt;br /&gt;
attributes = [&amp;quot;http://creativecommons.org/ns#Distribution&amp;quot;,&lt;br /&gt;
		&amp;quot;http://creativecommons.org/ns#DerivativeWorks&amp;quot;,&lt;br /&gt;
		&amp;quot;http://creativecommons.org/ns#Attribution&amp;quot;,&lt;br /&gt;
		&amp;quot;http://creativecommons.org/ns#Notice&amp;quot;]&lt;br /&gt;
chooser = LicenseChooser(None,attributes)&lt;br /&gt;
chooser.get_licenses(permits=(1 &amp;lt;&amp;lt; 0) | (1 &amp;lt;&amp;lt; 1), requires=0, prohibits=0)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; ['http://creativecommons.org/licenses/publicdomain/']&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
LicenseChooser takes two arguments:&lt;br /&gt;
* The first is a string representing the jurisdiction of licenses to return.  In this case, we specify '''None''' to only return Unported licenses.  For example, &amp;quot;us&amp;quot; or &amp;quot;uk&amp;quot; would be acceptable input, for United States and United Kingdom licenses, respectively.&lt;br /&gt;
* The second is a list of attributes to search on.  Note: this is not Creative Commons specific -- you may specify any attributes in this list.&lt;br /&gt;
&lt;br /&gt;
Now that we have a LicenseChooser, we can query it for licenses based on flags.  There's a bit of voodoo here, but I hope that you can follow by example.  Let's start with this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;(1 &amp;lt;&amp;lt; 0) | (1 &amp;lt;&amp;lt; 1)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are the '''permits''' flags from the above example.  What this says is that we want licenses that permit the 0th and 1st attribute in the '''attributes''' list -- in other words, licenses that permit Distribution and DerivativeWorks.  Flags we don't care about (in this example, '''requires''' and '''prohibits'''), we set to zero.  Alternatively, they can be left out altogether.&lt;br /&gt;
&lt;br /&gt;
Because we also specified the Attribution and Notice attributes, the above query will return licenses that do not permit, require, or prohibit these attributes.  This particular query returns one license: Public Domain.&lt;br /&gt;
&lt;br /&gt;
==== PyGTK Widget ====&lt;br /&gt;
Now that we have the basics for how the LicenseChooser works, we are going to build the following  license selection widget using PyGTK.  Because it is included with Liblicense, I'll only explain the relevant parts of the code.  The full source is available here: [http://cctools.svn.sourceforge.net/viewvc/cctools/liblicense/trunk/src/gnome/gui_gtk.py.in?revision=6398&amp;amp;view=markup http://cctools.svn.sourceforge.net/viewvc/cctools/liblicense/trunk/src/gnome/gui_gtk.py.in].&lt;br /&gt;
&lt;br /&gt;
My hope is that this short tutorial will help in creating license choosers using other graphical toolkits and other languages.&lt;br /&gt;
&lt;br /&gt;
[[Image:GTK_LicenseChooser.png]]&lt;br /&gt;
&lt;br /&gt;
First off, I'll assume you've built the above GUI.  You should have something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import gtk&lt;br /&gt;
import gobject&lt;br /&gt;
import liblicense&lt;br /&gt;
&lt;br /&gt;
class LicenseWidget(gtk.VBox):&lt;br /&gt;
    __gsignals__ = {&amp;quot;changed&amp;quot;:(gobject.SIGNAL_RUN_FIRST,gobject.TYPE_NONE,(gobject.TYPE_STRING,))}&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
       # Build your GUI here       &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should have 5 gtk.CheckButton's.&lt;br /&gt;
* self.ash: Allow Sharing&lt;br /&gt;
* self.ar : Allow Remixing&lt;br /&gt;
* self.pcw: Prohibit Commercial Works&lt;br /&gt;
* self.sa : Require Share-Alike&lt;br /&gt;
* self.by : Require Attribution&lt;br /&gt;
&lt;br /&gt;
And 2 gtk.Entry's.&lt;br /&gt;
* self.uri     : Displays the URI of the matching license&lt;br /&gt;
* self.license : Displays the name of the matching license&lt;br /&gt;
&lt;br /&gt;
Note that you could use any attributes and any number of attributes you would like.  These 5 fit well with Creative Commons licenses.&lt;br /&gt;
&lt;br /&gt;
We will also create the license chooser in '''__init__'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
       attributes = [&amp;quot;http://creativecommons.org/ns#Attribution&amp;quot;,&lt;br /&gt;
                     &amp;quot;http://creativecommons.org/ns#Distribution&amp;quot;,&lt;br /&gt;
                     &amp;quot;http://creativecommons.org/ns#DerivativeWorks&amp;quot;,&lt;br /&gt;
                     &amp;quot;http://creativecommons.org/ns#CommercialUse&amp;quot;,&lt;br /&gt;
                     &amp;quot;http://creativecommons.org/ns#ShareAlike&amp;quot;]&lt;br /&gt;
       self.ll_chooser = liblicense.LicenseChooser(None,attributes)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now let's connect the five buttons up.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        self.by.connect(&amp;quot;toggled&amp;quot;,self.checkbox_toggled,0)&lt;br /&gt;
        self.ash.connect(&amp;quot;toggled&amp;quot;,self.checkbox_toggled,1)&lt;br /&gt;
        self.ar.connect(&amp;quot;toggled&amp;quot;,self.checkbox_toggled,2)&lt;br /&gt;
        self.pcw.connect(&amp;quot;toggled&amp;quot;,self.checkbox_toggled,3)&lt;br /&gt;
        self.sa.connect(&amp;quot;toggled&amp;quot;,self.checkbox_toggled,4)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here's what we'll do when a checkbox is clicked.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def checkbox_toggled(self,button,flag):&lt;br /&gt;
        self.update_license()&lt;br /&gt;
&lt;br /&gt;
    def update_license(self):&lt;br /&gt;
        licenses = self.ll_chooser.get_licenses(&lt;br /&gt;
          permits=(self.ash.get_active()&amp;lt;&amp;lt;1) | (self.ar.get_active()&amp;lt;&amp;lt;2),&lt;br /&gt;
          requires=(self.by.get_active()&amp;lt;&amp;lt;0) | (self.sa.get_active()&amp;lt;&amp;lt;4),&lt;br /&gt;
          prohibits=(self.pcw.get_active()&amp;lt;&amp;lt;3))&lt;br /&gt;
&lt;br /&gt;
        if licenses:&lt;br /&gt;
            uri = licenses[0]&lt;br /&gt;
            self.emit(&amp;quot;changed&amp;quot;,uri)&lt;br /&gt;
            self.uri.set_text(uri)&lt;br /&gt;
            v = liblicense.get_version(uri)&lt;br /&gt;
            self.license.set_text(&amp;quot;%s - %d.%d.%d&amp;quot; % (liblicense.get_name(u), v[0], v[1], v[2]))&lt;br /&gt;
        else:&lt;br /&gt;
            self.uri.set_text(&amp;quot;&amp;quot;)&lt;br /&gt;
            self.license.set_text(&amp;quot;none&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I'll break this down.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        licenses = self.ll_chooser.get_licenses(&lt;br /&gt;
          permits=(self.ash.get_active()&amp;lt;&amp;lt;1) | (self.ar.get_active()&amp;lt;&amp;lt;2),&lt;br /&gt;
          requires=(self.by.get_active()&amp;lt;&amp;lt;0) | (self.sa.get_active()&amp;lt;&amp;lt;4),&lt;br /&gt;
          prohibits=(self.pcw.get_active()&amp;lt;&amp;lt;3))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are those voodoo flags again.  The important thing to realize is that the above numbers correspond to the index in the '''attributes''' array.  If get_active() returns False, then that component drops out of the expression and is effectively ignored.  Otherwise, the correct bit is set.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        if licenses:&lt;br /&gt;
            uri = licenses[0]&lt;br /&gt;
            self.emit(&amp;quot;changed&amp;quot;,uri)&lt;br /&gt;
            self.uri.set_text(uri)&lt;br /&gt;
            v = liblicense.get_version(uri)&lt;br /&gt;
            self.license.set_text(&amp;quot;%s - %d.%d.%d&amp;quot; % (liblicense.get_name(u), v[0], v[1], v[2]))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A license matched, so we'll use liblicense to get the name and version of the license to display, along with the URI.  Note that the LicenseChooser returned a list of licenses.  For simplicity, we'll only display the first in the list.  We'll also emit the &amp;quot;changed&amp;quot; signal so that the application is notified of the license change.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        else:&lt;br /&gt;
            self.uri.set_text(&amp;quot;&amp;quot;)&lt;br /&gt;
            self.license.set_text(&amp;quot;none&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
No license matched so we do a bit of cleanup.&lt;br /&gt;
&lt;br /&gt;
And that's about it.  I won't cover the details of jurisdiction at the moment, but this can easily be accomplished by creating a new LicenseChooser with the appropriate jurisdiction whenever a new jurisdiction is selected.&lt;br /&gt;
&lt;br /&gt;
=== C bindings ===&lt;br /&gt;
&lt;br /&gt;
Here is a complete, standalone example using the C bindings.  Integration into applications follows similarly to the Python bindings above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;liblicense.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  ll_init();&lt;br /&gt;
  &lt;br /&gt;
  char *attributes[] = {&lt;br /&gt;
    &amp;quot;http://creativecommons.org/ns#Distribution&amp;quot;,&lt;br /&gt;
    &amp;quot;http://creativecommons.org/ns#CommercialUse&amp;quot;,&lt;br /&gt;
    &amp;quot;http://creativecommons.org/ns#DerivativeWorks&amp;quot;,&lt;br /&gt;
    &amp;quot;http://creativecommons.org/ns#ShareAlike&amp;quot;,&lt;br /&gt;
    &amp;quot;http://creativecommons.org/ns#Attribution&amp;quot;,&lt;br /&gt;
    NULL&lt;br /&gt;
  };&lt;br /&gt;
  ll_license_chooser_t *chooser = ll_new_license_chooser(NULL,attributes);&lt;br /&gt;
&lt;br /&gt;
  int permits, requires, prohibits;&lt;br /&gt;
&lt;br /&gt;
  //permits Distribution(0) and DerivativeWorks(2)&lt;br /&gt;
  permits = (1 &amp;lt;&amp;lt; 0) | (1 &amp;lt;&amp;lt; 2);&lt;br /&gt;
&lt;br /&gt;
  //requires ShareAlike(3) and Attribution(4)&lt;br /&gt;
  requires = (1 &amp;lt;&amp;lt; 3) | (1 &amp;lt;&amp;lt; 4);&lt;br /&gt;
&lt;br /&gt;
  //prohibits CommericalUse(1)&lt;br /&gt;
  prohibits = (1 &amp;lt;&amp;lt; 1);&lt;br /&gt;
&lt;br /&gt;
  const ll_license_list_t *licenses = ll_get_licenses_from_flags(chooser,permits,requires,prohibits);&lt;br /&gt;
  while (licenses) {&lt;br /&gt;
    printf(&amp;quot;%s\n&amp;quot;,licenses-&amp;gt;license);&lt;br /&gt;
    licenses = licenses-&amp;gt;next;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  ll_free_license_chooser(chooser);&lt;br /&gt;
  ll_stop();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Command-line Interface ==&lt;br /&gt;
[[Incomplete]]&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Insert non-formatted text here&amp;lt;/nowiki&amp;gt;HSAENZL EN WEB[[Image:Example.jpg]]YAHOO[[Image:Example.jpg]]HSAENZ&lt;br /&gt;
== Headline text ==[[Media:Example.ogg]]&lt;/div&gt;</summary>
		<author><name>HSAENZL</name></author>	</entry>

	<entry>
		<id>https://wiki.creativecommons.org/index.php?title=Talk:Content_Directories&amp;diff=8304</id>
		<title>Talk:Content Directories</title>
		<link rel="alternate" type="text/html" href="https://wiki.creativecommons.org/index.php?title=Talk:Content_Directories&amp;diff=8304"/>
				<updated>2007-08-06T22:27:23Z</updated>
		
		<summary type="html">&lt;p&gt;HSAENZL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;math&amp;gt;Insert formula here&amp;lt;/math&amp;gt;== how much content is needed for inclusion and how to promote a CC site?? ==&lt;br /&gt;
&lt;br /&gt;
I started an [http://saponaceo.us open soapmaking wiki] in which all content is Creative Commons licensed.  So far I've had difficulty (and resistance) promoting it among the soapmaking community through Yahoo! groups.  I went about promoting it the wrong way, but there's no help from google or other search engines, even when you try really hard to find a free soapmaking content site.  Try as you might, it just doesn't have the 'pagerank' to be useful.  I think I might just continue to put content into it myself, and if it doesn't take off, I'll turn what I have at that point into a book and sell it.  But this of course defeats the purpose of CC licensed info.  If anyone can help, please help me.  People's response to me so far is that I have something to gain from hosting and trying to promote the site.  I'm not even running ads.  I work as a web developer.  This is supposed to be a build it and they will come type of thing.  I have one other moderator.  There seems to be a trust disconnect.  Maybe there's just not enough information there yet.  Please reply to mchrisneglia . at . yahoo.com.  [http://mchrisneglia.info or find me here]&lt;br /&gt;
&lt;br /&gt;
simuze and promocioname need to be re-added&lt;br /&gt;
&lt;br /&gt;
openphoto.net?&amp;lt;math&amp;gt;Insert formula here&amp;lt;/math&amp;gt;HECTOR^+LOPEZ&lt;br /&gt;
&lt;br /&gt;
== agnula libre music has been down for months ==[[Image:Example.jpg]]GOOGLE&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== wow, I have to say I love creative commons in theory ==&lt;br /&gt;
...practice not so much.  I made an album, it went out of print thanks to Tower Records so I decided that I wanted to give it away, its a christmas record, but not a sucky one so I t seemed in keeping with the spirt.  I gave it a creative commons license. So that it could live new exciting lives as soundtracks or samples or what have you.  I wanted to list it so that  it could be  searchable within CC.   Almost two hours later I have yet to find a place to put anything.  Now if i had remixed my music, there are forty places to do that.  but where can you give something, thats not remixed? it seems like a simple content directory would be so much more useful. uggh sorry I know this isn't the ranting space, that is probably hid under some obscure sub menu three levels down, &lt;br /&gt;
&lt;br /&gt;
so heres the deal if someone wants  to  list this somewhere cool&lt;br /&gt;
its a christmas record: Snaildartha : the story of Jerry the Christmas Snail-which is more a less a retelling of the life of Buddha...only through a  Holiday snail.. and its Soul Jazz.&lt;br /&gt;
&lt;br /&gt;
Currently  it lives here Snaildartha[http://www.alliedchemical.com/~snaildartha]&lt;br /&gt;
&lt;br /&gt;
If someone doesn't want to list it somewhere, thats fine too,&lt;br /&gt;
&lt;br /&gt;
==Agnula Libre Music==&lt;br /&gt;
* Main URL: http://muzik.agnula.org/&lt;br /&gt;
* CC-only portal: almost everything is CC-licensed (some EFF OAL)&lt;br /&gt;
* CC-only feed: ?&lt;br /&gt;
* Formats: audio&lt;br /&gt;
* Size and scope of CC-licensed collection: ?&lt;br /&gt;
* Notes:&lt;br /&gt;
&lt;br /&gt;
Removed this from the article. [[User:Mike Linksvayer|Mike Linksvayer]] 21:00, 3 July 2006 (UTC)&lt;br /&gt;
&lt;br /&gt;
I would like to ad a new section for this but I don't know how..&lt;/div&gt;</summary>
		<author><name>HSAENZL</name></author>	</entry>

	<entry>
		<id>https://wiki.creativecommons.org/index.php?title=CcHost_File_Access&amp;diff=8303</id>
		<title>CcHost File Access</title>
		<link rel="alternate" type="text/html" href="https://wiki.creativecommons.org/index.php?title=CcHost_File_Access&amp;diff=8303"/>
				<updated>2007-08-06T22:16:44Z</updated>
		
		<summary type="html">&lt;p&gt;HSAENZL: /* ccHost Permissions Policy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Information regarding UNIX file permission and ccHost== &lt;br /&gt;
&lt;br /&gt;
Setting file permissions in the most efficient and secure way can be tricky with &lt;br /&gt;
a content management system such as ccHost on a UNIX system.&lt;br /&gt;
&lt;br /&gt;
There are many (i.e. many, many) UNIX configurations for running Apache and PHP &lt;br /&gt;
and this document does not pretend to cover all. It is a compendium of issues &lt;br /&gt;
encountered by various ccHost installations under some popular scenarios. If &lt;br /&gt;
there are security issues on your server with ccHost or you would like to avoid &lt;br /&gt;
them, hopefully this document will arm you with enough information to ask your &lt;br /&gt;
system administrator the right questions.&lt;br /&gt;
&lt;br /&gt;
If you 'own' the server and have super-user (root) access then these problems &lt;br /&gt;
are probably moot because you have the rights to do whatever you want with the  &lt;br /&gt;
directories and files created by ccHost. However, depending on whether you run PHP &lt;br /&gt;
in CGI mode or not, these issues could very well be a big problem.&lt;br /&gt;
&lt;br /&gt;
On the other hand if you are using a company server or a &lt;br /&gt;
web hosting service, especially&lt;br /&gt;
on a 'shared server', then chances are you do not have such&lt;br /&gt;
access rights and that's where the issues begin.&lt;br /&gt;
&lt;br /&gt;
In either case the thing to understand is that on a UNIX&lt;br /&gt;
system: Whoever creates a file or directory on UNIX typically has full&lt;br /&gt;
(or enough) access rights to that file or directory to do what&lt;br /&gt;
ever they like.'''&lt;br /&gt;
&lt;br /&gt;
=== You are not nobody=== &lt;br /&gt;
&lt;br /&gt;
When you sign on to your web server via a terminal application (i.e.&lt;br /&gt;
shell) or transfer files via FTP you are operating as &lt;br /&gt;
whoever you logged in as. When you copy the ccHost installation&lt;br /&gt;
onto your server (or unzip them directly there) the directories &lt;br /&gt;
you create and files you copy into them are under your jurisdiction &lt;br /&gt;
and UNIX considers you the 'user' (you 'own' them).&lt;br /&gt;
&lt;br /&gt;
When ccHost is running on a UNIX server it is considered &lt;br /&gt;
a PHP browser application running in an instance of Apache. Your&lt;br /&gt;
server administrator has set up all PHP applications like ccHost&lt;br /&gt;
to run, not as you, but as a special user, usually called 'nobody' &lt;br /&gt;
and UNIX considers 'nobody' to be the user who owns the directory&lt;br /&gt;
and files.&lt;br /&gt;
&lt;br /&gt;
The main point is: These are two very distinctly different identities and the directories&lt;br /&gt;
and files created by ccHost are owned by this 'nobody' account, not you.&lt;br /&gt;
&lt;br /&gt;
Evidence can be seen when you list out the directories in your ccHost&lt;br /&gt;
installation:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
drwxrwxr-x   5 victor wgroup  4096 Jul 15 01:41 cctools &lt;br /&gt;
drwxrwxr-x   5 nobody wgroup  4096 Jul 17 02:09 contests&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first directory 'cctools' created by me during FTP install. The second directory 'contests' was created by ccHost when I said 'Create Contest' and is therefore owned by another user.&lt;br /&gt;
&lt;br /&gt;
=== What ccHost Requires (IMPORTANT)=== &lt;br /&gt;
&lt;br /&gt;
For 3.1 installations and later: The path configuration screen (Global Settings/Paths) will let you know exactly which directories require write access from script. These include 'people', 'constests', your log directory and my_files/temp. These last two depend on where you specified their locations during installation. NOTE: ''Your installation will not work properly until my_files/temp is writable to script.''&lt;br /&gt;
&lt;br /&gt;
For installations previous to 3.1: In order to install properly, ccHost (or more precisely the PHP account ccHost is running as) must have write permissions in the root directory of the ccHost installation, in a directory under it called '''cclib/phptal/phptal_cache''' and where ever you told the installation to put log files to. Specifically and in UNIX parlance this means full permission: Read, Write and Execute. The '''people''' directory is normally created by ccHost the first time something is uploaded and the '''contests''' directory is normally created the first time something is uploaded into a contest. If these directories already exist then ccHost will only need permissions in them, '''cclib/phptal/phptal_cache''' and your logfile directory -- not the root. Instructions for how to set these up (and whether you even have to) are covered below.&lt;br /&gt;
&lt;br /&gt;
=== Case 1: You and ccHost are the same user=== &lt;br /&gt;
&lt;br /&gt;
In the best case scenario, some web hosters make all of this go away by &lt;br /&gt;
simply having PHP applications run under the same account as your login account. &lt;br /&gt;
There is no 'nobody' account to contend with and ccHost is, in fact, running as you&lt;br /&gt;
so permission to create directories in the main directory or write files to &lt;br /&gt;
the phptal_cache directory is given. So if you ask your system administrator&lt;br /&gt;
'Do PHP apps run under my user's account?' and if the answer is 'Yes' then you &lt;br /&gt;
can skip down the ccHost policy section because none of &lt;br /&gt;
this applies to your ccHost installation.&lt;br /&gt;
&lt;br /&gt;
=== Case 2: You and ccHost are in the same group=== &lt;br /&gt;
&lt;br /&gt;
The next question you have to ask is whether your account and PHP account&lt;br /&gt;
is in the same group. You can see in the listing first mentioned &lt;br /&gt;
above that this is case:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
drwxrwxr-x   5 victor wgroup  4096 ....&lt;br /&gt;
drwxrwxr-x   5 nobody wgroup  4096 ....&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is important because while you may not be the same user as&lt;br /&gt;
the PHP account, UNIX has another level of security called group before&lt;br /&gt;
getting to the global space (the rest of the world).&lt;br /&gt;
If this is the case then you should consider restricting the directories that need writing access to only owner and group.&lt;br /&gt;
&lt;br /&gt;
The way to traditionally do this is to run the chmod command as such:&lt;br /&gt;
&lt;br /&gt;
 chmod 775 folder&lt;br /&gt;
&lt;br /&gt;
Or, for all files under the folder recursively:&lt;br /&gt;
&lt;br /&gt;
 chmod -R 775 folder&lt;br /&gt;
&lt;br /&gt;
And/or, just to give the group full read (r), write (w) and execute (x) privileges:&lt;br /&gt;
&lt;br /&gt;
 chmod -R g+rwx folder&lt;br /&gt;
&lt;br /&gt;
=== Case 3: You and ccHost are not in the same group=== &lt;br /&gt;
&lt;br /&gt;
If your personal UNIX login account and your PHP account are not even in the &lt;br /&gt;
same group then you may still have an out:&lt;br /&gt;
&lt;br /&gt;
Some web hosting companies provide you with a secure browser based&lt;br /&gt;
interface that allows you to bridge difference in user rights by giving you&lt;br /&gt;
behind-the-scenes circumvention to ownership issues in your space&lt;br /&gt;
on the server. When the ccHost&lt;br /&gt;
documentation prescribes things like 'setting write permissions on a &lt;br /&gt;
directory' you should use this secure web interface provided by your&lt;br /&gt;
web hoster to perform the action. When you need to make changes to the &lt;br /&gt;
files, use this interface. That way it won't matter if the&lt;br /&gt;
'nobody' account or your account created the directory or file, &lt;br /&gt;
you can make the needed change.&lt;br /&gt;
&lt;br /&gt;
If your personal UNIX login account and your PHP account are not in the same group and you haven't a secure web interface, then your system administrator or web hosting service has left you with no choice to make the necessary directories available for writing to global users (a.k.a. other). You should keep the ccHost default access permission at 777.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Headline text ==&lt;br /&gt;
== ccHost Permissions Policy== &lt;br /&gt;
ccHost 3.0 will use 0777 as the default for creating files. This is so new installations can get quickly off the ground and running. If you wish to change this policy go to 'Manage Site' and then 'Global Settings.'&lt;br /&gt;
&amp;lt;math&amp;gt;Insert formula here&amp;lt;/math&amp;gt;[[Image:Example.jpg]]&lt;br /&gt;
--[[User:HSAENZL|HSAENZL]] 18:16, 6 August 2007 (EDT)&amp;lt;math&amp;gt;Insert formula here&amp;lt;/math&amp;gt;^7E/e''Italic text''hectorlopez&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Link title]]bienvinido&lt;/div&gt;</summary>
		<author><name>HSAENZL</name></author>	</entry>

	<entry>
		<id>https://wiki.creativecommons.org/index.php?title=CCWiki_talk:Administrators&amp;diff=8298</id>
		<title>CCWiki talk:Administrators</title>
		<link rel="alternate" type="text/html" href="https://wiki.creativecommons.org/index.php?title=CCWiki_talk:Administrators&amp;diff=8298"/>
				<updated>2007-08-06T20:00:42Z</updated>
		
		<summary type="html">&lt;p&gt;HSAENZL: New page: [http://www.example.com link title] hector '''Bold text'''deseo feliz &amp;lt;page&amp;gt;&amp;lt;math&amp;gt;Insert formula here&amp;lt;/math&amp;gt;7^+e[goto] --~~~~ == Headline text == pagedihector^web&amp;lt;math&amp;gt;Insert formula here&amp;lt;...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.example.com link title] hector&lt;br /&gt;
'''Bold text'''deseo feliz &amp;lt;page&amp;gt;&amp;lt;math&amp;gt;Insert formula here&amp;lt;/math&amp;gt;7^+e[goto]&lt;br /&gt;
--[[User:HSAENZL|HSAENZL]] 16:00, 6 August 2007 (EDT)&lt;br /&gt;
== Headline text ==&lt;br /&gt;
pagedihector^web&amp;lt;math&amp;gt;Insert formula here&amp;lt;/math&amp;gt;87^e+a&lt;br /&gt;
[http://www.example.com link title]&lt;br /&gt;
== Headline text ==&lt;/div&gt;</summary>
		<author><name>HSAENZL</name></author>	</entry>

	</feed>