<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.mediagoblin.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tryggvib</id>
	<title>GNU MediaGoblin Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.mediagoblin.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tryggvib"/>
	<link rel="alternate" type="text/html" href="https://wiki.mediagoblin.org/Special:Contributions/Tryggvib"/>
	<updated>2026-05-25T15:17:19Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.17</generator>
	<entry>
		<id>https://wiki.mediagoblin.org/index.php?title=Main_Page&amp;diff=1051</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.mediagoblin.org/index.php?title=Main_Page&amp;diff=1051"/>
		<updated>2012-12-29T12:59:50Z</updated>

		<summary type="html">&lt;p&gt;Tryggvib: Undo revision 1048 by Patrica11upps (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Want to Join the MediaGoblin Community? =&lt;br /&gt;
&lt;br /&gt;
We’re really glad that you want to join the MediaGoblin community!&lt;br /&gt;
&lt;br /&gt;
There are a variety of ways to help and support MediaGoblin and to join the team.  If you want to code, great, if not, even better!  MediaGoblin interested contributors in many different roles: users, system administrators, technical writers, testers, evangelists, UI/UX and graphics designers, cheerleaders, and dreamers.&lt;br /&gt;
&lt;br /&gt;
This wiki covers a variety of ways that you can get involved with MediaGoblin as well as instructions on how to get started.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hang out with the MediaGoblin folk ==&lt;br /&gt;
&lt;br /&gt;
MediaGoblin has a mailing list and an IRC channel where we hang out.  See [http://mediagoblin.org/pages/join.html our join page] for links.&lt;br /&gt;
&lt;br /&gt;
Please drop by and say “Hi!”  And, if you’re looking for something to do, just ask---there’s always work to be done.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Take Part in the Monthly Meetings ==&lt;br /&gt;
&lt;br /&gt;
Each month is a [[Meeting]]. You can take part and help decide on the future of MediaGoblin. Or just be around and see what&#039;s happening live!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== File Bugs / Triage Bugs ==&lt;br /&gt;
&lt;br /&gt;
Issue reports are critical for all projects.  Identified bugs give developers a basis for beginning work, and providing an idea of what features and issues are most important to users and the overall usability of the software.  If you identify errors, flaws, unexpected behaviors, or deficits that impede use, file a bug.&lt;br /&gt;
&lt;br /&gt;
* [[File Bugs]] -- notes on filing new bugs/issues/feature requests&lt;br /&gt;
* [[Feature Ideas]] -- notes on possible features&lt;br /&gt;
* [[Triage Bugs]] -- notes on triaging&lt;br /&gt;
* [[BugTriageDay]] -- every other Thursday is bug triage day where anyone can help out triaging bugs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Write Code / Fix Code ==&lt;br /&gt;
&lt;br /&gt;
If you are a coder and you would like to write code, the repository is hosted on gitorious. Clone or fork the repository and start poking around. Become familiar with this manual for an overview of how the software works and is used. Consider the contributor wiki for more information about the project, our preferred methods, and guides for developing MediaGoblin. We even have tips on becoming a coder and we’re willing to help!&lt;br /&gt;
&lt;br /&gt;
* [[HackingHowto|Hacking]] - notes on making and sending in code contributions&lt;br /&gt;
** [[BeginnersCorner|Beginner&#039;s Corner]] - resources for those who are new to Python or Git.&lt;br /&gt;
** &#039;&#039;Started from an older version of the Hacking Howto?  We switched from buildout-&amp;gt;virtualenv, so look at [[Moving from buildout to virtualenv]] for information on how to move over.&#039;&#039;&lt;br /&gt;
* [[Git workflow]] - How to go about submitting patches via git.&lt;br /&gt;
* [[Templating]] - How our templating structure is set up&lt;br /&gt;
* [[Code overview]] - Overview of the structure of the codebase&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Send Encouragement / Spread the Word ==&lt;br /&gt;
&lt;br /&gt;
Sometimes, a nice word, simple encouragement, and interest in the work we’re doing is enough to inspire a tizzy of productive work.  Just a bit more interest and encouragement can even make the difference between a complete feature and limited functionality; between a completed milestone and lost momentum.&lt;br /&gt;
&lt;br /&gt;
Similarly, MediaGoblin, and the movement for free network services, is always in need of encouragement.  Use free network services, understand the principals behind the movement, be able to articulate the benefits of free network services and the problems with psudo-free applications that don’t respect the users’ freedom.&lt;br /&gt;
&lt;br /&gt;
Write a blog post, post a status update, drop by the listserv or join #mediagoblin on freenode.net and let us know.  See [http://mediagoblin.org/join/ our join page] for links.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Write Documentation / Edit Documentation ==&lt;br /&gt;
&lt;br /&gt;
* [[Documentation quick start]] - How to contribute to the documentation effort.&lt;br /&gt;
* [[ManualStandards]] - covers the standards for writing the user manual (forthcoming.) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Test MediaGoblin ==&lt;br /&gt;
&lt;br /&gt;
Do you have access to the web? Do you like sharing your opinions? If so, we need your help to test MediaGoblin! Testers play around with the current test instance, note what operating system and browser they use (notes on multiple set-ups are also helpful) and take some notes. That&#039;s it! It&#039;s a very important task that doesn&#039;t require any special knowledge and you&#039;re done in under an hour. Ready to help?  &lt;br /&gt;
&lt;br /&gt;
* [[User Experience]] - user experience testing.  Includes link to an instance you can try!&lt;br /&gt;
* [[UnitTests|Unit Tests]] - all about the unit tests&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Translate MediaGoblin ==&lt;br /&gt;
&lt;br /&gt;
If you know English and another language and feel comfortable translating elements of the interface or even the documentation, we’d love to have help translating the software and resources.&lt;br /&gt;
Translating MediaGoblin is very easy with a web interface, so there is no programming knowledge required at all.&lt;br /&gt;
&lt;br /&gt;
* [[Translations]] - How to translate stuff or update the translations&lt;br /&gt;
&lt;br /&gt;
== Become a User ==&lt;br /&gt;
&lt;br /&gt;
Coming soon!&lt;br /&gt;
&lt;br /&gt;
We’re building MediaGoblin for us and for you but really you’re one of us and I am you and we are we and MediaGoblin is the walrus.&lt;br /&gt;
&lt;br /&gt;
We&#039;re planning to launch our own public instance of MediaGoblin in the near future--probably in the September/October 2011 time frame.  When we do, sign up for an account, use the service and relish in the thought that this service comes with a heaping side of Freedom and you can salt and pepper it to your liking.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Help Others ==&lt;br /&gt;
&lt;br /&gt;
Have you spent time with MediaGoblin?  If so, your experience and wisdom are invaluable and you’re the best person we can think of to help other users with their questions.&lt;br /&gt;
&lt;br /&gt;
Hang out on the IRC channel and help answer new peoples&#039; questions.  See [http://mediagoblin.org/join/ our join page] for links.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Run your own MediaGoblin Instance ==&lt;br /&gt;
&lt;br /&gt;
Are there things about our instance you want to change?  Are there things about other instances you wish were different?  Want to test upcoming changes?  Want to create patches to implement things you need?  That’s great—you can run your own instance!&lt;br /&gt;
&lt;br /&gt;
* [[Configure_MediaGoblin|Configuration]] - Learn about MediaGoblin configuration files and file options.&lt;br /&gt;
* [[Deployment]] - General deployment advice&lt;br /&gt;
* [[Scaling Down]] - Minimizing MediaGoblin&#039;s resource requirements&lt;br /&gt;
* [[Virtual Machine Hosting]] - Deploy your own publicly available MediaGoblin server using [http://aws.amazon.com/free/?utm_source=adwords&amp;amp;utm_medium=cpc&amp;amp;utm_campaign=CPC_Google_AWS_ec2&amp;amp;utm_content=TextV01_PP_V01_EC2&amp;amp;trk=CPC_Google_AWS_ec2 Amazon&#039;s free EC2 tier].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Create a Theme ==&lt;br /&gt;
&lt;br /&gt;
Coming soon!&lt;br /&gt;
&lt;br /&gt;
MedaGoblin development is premised on the idea that the entire interface for the platform be completely theme-able.  If you have a design or theming background, consider developing themes for MediaGoblin.  New themes help test the theming system, provide attractive and appealing interfaces for prospective users.  If you want to start a new theme but don’t know where to start, touch base with the development community on the list or in the IRC channel for more information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Technical project documentation =&lt;br /&gt;
&lt;br /&gt;
* [[DesignDecisions]] - covers design decisions (FIXME - this needs to be split up)&lt;br /&gt;
* [[Storage]] - How MediaGoblin&#039;s internal storage system works.&lt;br /&gt;
* [[Processing]] - What happens after you submit your image/video/etc?  Processing!  More about that.&lt;br /&gt;
* [https://gitorious.org/mediagoblin/mediagoblin/blobs/master/extlib/README External Library Policy] - covers use of external libraries&lt;br /&gt;
* [[User:Cwebber/braindumps]] - Chris Webber&#039;s braindumps (you can help refactoring these into real sections of the site!)&lt;br /&gt;
* [[Multiple media support]] - Design plan for multiple media support&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Inner workings of the secret sanctum =&lt;br /&gt;
&lt;br /&gt;
* [[IRCBot]] - covers our irc bot&lt;br /&gt;
* [[ReleaseProcess|Release Process]] - covers the release process&lt;br /&gt;
* [[Update the website]] - Learn how to update mediagoblin.org!&lt;/div&gt;</summary>
		<author><name>Tryggvib</name></author>
	</entry>
	<entry>
		<id>https://wiki.mediagoblin.org/index.php?title=Main_Page&amp;diff=1050</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.mediagoblin.org/index.php?title=Main_Page&amp;diff=1050"/>
		<updated>2012-12-29T12:59:32Z</updated>

		<summary type="html">&lt;p&gt;Tryggvib: Undo revision 1049 by Patrica22upps (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It a multi functional combination for  [http://www.mkol.us michael kors handbags] instance particular emblems all of which equals a multi function put together for instance bar lines. These bar lines are offered on temporary,far together with various spaces bewteen barefoot and shoes. Without it applications,the choices procedure that was spoke of that has reached over is mainly because all the way through unimaginable to find performed. &lt;br /&gt;
&lt;br /&gt;
There aren&#039;t any handbags in blue, brown or red. But Coach lead a trend of developing bags in Pink as well as other colors. Now, you will observe most bags of Coach are typically in pink or blue. Then came the Lv Black Murakami Collection. Not only will you start to see the wanna be girls for the mall, hoping that in case they turn the tag in and don let anyone be aware of the clasp, they may just get individuals reckon that they carrying a geniune LV bag. You are aware of the visible difference. &lt;br /&gt;
&lt;br /&gt;
It is best to decide washable fabrics,burberry bags who have a fine texture. Make sure to get yourself a bag set that has a pocket within 3-5 inches with the mattress depth to prevent yourself from  [http://www.mkmk.us michael kors outlet] slippage. The thread-count in the bed  [http://www.headphonesbybeats.com beats by dre] sheet is why the sheets durable and soft, so be sure you choose sheets of high thread-count. &lt;br /&gt;
&lt;br /&gt;
In the huge money that cost about the designer bag,  [http://www.shoptnf.com north face outlet] you can easily do all kinds of other significant things. So inevitably, from any of the Designer bags during my wardrobe are replica bags. Keep in mind, I never embarrass myself for carrying the replica Dior bags, Replica Chanel bags and Replica LV bags. &lt;br /&gt;
&lt;br /&gt;
Size is important. The larger the better for many, and small, small persons. Design for a large bag will change the selling price when it is a very high end designer purse. Credibility - When you finally would&#039;ve provided your phrase, if or not it&#039;s truly a promise or perhaps not, do this. A poor impression was developed rrnside your boss by chance you usually do not use a term of honor. In some way, it tends to make you peer to get an untrustworthy person. &lt;br /&gt;
&lt;br /&gt;
Or if at all close family celebration, you would possibly  have every balloon printed together with your family photograph. Also, assume associated with an awesome phrase of greetings as you will also make sure they printed blended with pics. The greetings will express your feelings and ideas to the celebrant, or simply a method of expressing the style the celebration was created for. &lt;br /&gt;
&lt;br /&gt;
Now, lots of personal funds to overseas, however it is big, it will likewise make foreign rates rising, overseas to bid the cost real, to work as China&#039;s skill and ability. Another way to point out that China&#039;s rich bought abroad, you get some foreign countries economy recovers, reducing high unemployment rates, a change in the economical situation. The rapid progression of China&#039;s economy, plus &amp;quot;rescued&amp;quot; by some Western countries appears to be cheap. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
http://metropolistower.com/wiki/index.php5/index.php?title=&lt;br /&gt;
http://instrumentisto.com/index.php/index.php?title=&lt;br /&gt;
http://readme.campus.mephi.ru/index.php?title=&lt;br /&gt;
http://www.virtualurth.com/index.php/member/420448/&lt;/div&gt;</summary>
		<author><name>Tryggvib</name></author>
	</entry>
	<entry>
		<id>https://wiki.mediagoblin.org/index.php?title=Personas&amp;diff=978</id>
		<title>Personas</title>
		<link rel="alternate" type="text/html" href="https://wiki.mediagoblin.org/index.php?title=Personas&amp;diff=978"/>
		<updated>2012-11-08T10:22:19Z</updated>

		<summary type="html">&lt;p&gt;Tryggvib: Description of Personas and three personas added: Gavroche (from joar), Shaquannah and Spencer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Personas&#039;&#039;&#039; in MediaGoblin development (not to be confused with [https://persona.org/ Mozilla Persona], formerly known as BrowserID) are a way to identify a specific target group of users via anthropomorphic goblins. This allows for a quick identification of a particular MediaGoblin user, e.g. in user stories.&lt;br /&gt;
&lt;br /&gt;
Personas should never be regarded as &#039;&#039;the&#039;&#039; only way to identify users and MediaGoblin developers should take care when using them since they might drive new developers off (instead of encouraging them to contribute). However these personas do make development more fun which in turn can encourage more people to participate. Ideally when using these personas in an environment accessible to &#039;&#039;would-be-developers&#039;&#039;, they should always be accompanied by their titles (user group) for clarification, i.e. &#039;&#039;Gavroche the artist uploads a new SVG image&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= Gavroche =&lt;br /&gt;
&lt;br /&gt;
== Title (user group) ==&lt;br /&gt;
&lt;br /&gt;
Artist&lt;br /&gt;
&lt;br /&gt;
== Bio ==&lt;br /&gt;
&lt;br /&gt;
Gavroche is an independent artist living in a suburb of Paris, France. Gavroche creates audible, text, visual and moving pictures often under the CC-BY-SA license.&lt;br /&gt;
&lt;br /&gt;
Gavroche is currently a GNOME3 user. Gavroche uses desktop applications such as&lt;br /&gt;
&lt;br /&gt;
* Blender, for animations and VFX&lt;br /&gt;
* Shotwell/digiKam, for digital photo development&lt;br /&gt;
* GIMP, for photo editing&lt;br /&gt;
* Vim/Emacs/$FOO &lt;br /&gt;
&lt;br /&gt;
Gavroche would like to be able to submit stuff directly from any of these applications, but he should not be required to launch any of them to be able to upload anything.&lt;br /&gt;
&lt;br /&gt;
= Shaquannah =&lt;br /&gt;
&lt;br /&gt;
== Title (user group) ==&lt;br /&gt;
&lt;br /&gt;
System administrator / sysadmin&lt;br /&gt;
&lt;br /&gt;
== Bio ==&lt;br /&gt;
&lt;br /&gt;
Shaquannah lives in a castle upon a hill, surrounded by farms and fields where lowly, plebeian goblins live. Contrary to the stereotypical castle-dweller she does not rule over her poor, neighbouring goblins. She tries to help and support them by the only charitable way imaginable. She runs a MediaGoblin instance for them. Thanks to Shaquannah the famished goblins, who live off the lands surrounding her castle, can take pictures and videos on their spiffy, expensive smartphones and upload them to a MediaGoblin instance where they serve as a documentation, a proof, of the tyranny of the other castle-dwelling neighbour (a weird little goblin who goes by the nickname &#039;&#039;The government&#039;&#039; - probably because he&#039;s the big brother of some lucky goblin).&lt;br /&gt;
&lt;br /&gt;
Shaquannah runs her MediaGoblin instance on a Debian based system. Shaquannah is able to write some code but she absolutely loves fiddling around with configurations and enabling this or that in the system (she goes all giddy when a small change from &amp;quot;false&amp;quot; to &amp;quot;true&amp;quot; allows for some breathtaking features that get her penniless neighbours to worship her all over again).&lt;br /&gt;
&lt;br /&gt;
In her spare time, Shaquannah enjoys kicking people out of her castle... they&#039;re interfering with her highly artistic sysadmin work!&lt;br /&gt;
&lt;br /&gt;
= Spencer =&lt;br /&gt;
&lt;br /&gt;
== Title (user group) ==&lt;br /&gt;
&lt;br /&gt;
Visitor / website viewer / guest&lt;br /&gt;
&lt;br /&gt;
== Bio ==&lt;br /&gt;
&lt;br /&gt;
Spencer lives in cyberspace. Does he have a home in meatspace? Nobody knows. His goal in life is to become a living, breathing goblin Google (his IRC handle is &#039;&#039;Goobln&#039;&#039;). To achieve this goal Spencer spends his entire day visiting all the websites he can find and memorizes its contents. He even visits the websites in different browsers just to be sure that the website developers don&#039;t serve up different content based on the user&#039;s browser.&lt;br /&gt;
&lt;br /&gt;
Spencer&#039;s favorite browsers are &#039;&#039;&#039;Mozilla Firefox&#039;&#039;&#039; and &#039;&#039;&#039;Google Chromium (Chrome)&#039;&#039;&#039; because they make cyberspace a better home for him, but he also secretly enjoys checking how websites handle &#039;&#039;restricted&#039;&#039; browsers, e.g. how the website is presented in a standards in-compliant browser such as Internet Explorer, how the website is presented in a text based browser such as Lynx, and how responsive the website is by visiting it via the smallest smartphone he can get his hands on (because everybody knows smartphones and hands exist in cyberspace).&lt;br /&gt;
&lt;br /&gt;
Websites that support all browsers score extra in Spencer&#039;s mental search engine ranking system.&lt;/div&gt;</summary>
		<author><name>Tryggvib</name></author>
	</entry>
	<entry>
		<id>https://wiki.mediagoblin.org/index.php?title=User:Joar/Proposed_usecase&amp;diff=973</id>
		<title>User:Joar/Proposed usecase</title>
		<link rel="alternate" type="text/html" href="https://wiki.mediagoblin.org/index.php?title=User:Joar/Proposed_usecase&amp;diff=973"/>
		<updated>2012-11-08T00:35:15Z</updated>

		<summary type="html">&lt;p&gt;Tryggvib: Made a link to a new page on Personas (will copy Gavroche description over there)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is the proposed default usecase for newly deployed GNU MediaGoblin applications.&lt;br /&gt;
&lt;br /&gt;
I learned that this kind of writing is called a &amp;quot;persona&amp;quot;, some might find it creepy. [[Personas]] help me to look beyond my own needs, to design the system for someone else rather than myself.&lt;br /&gt;
&lt;br /&gt;
= Gavroche =&lt;br /&gt;
&lt;br /&gt;
Gavroche is an independent artist living in a suburb of Paris, France. Gavroche creates audible, text, visual and moving pictures often under the CC-BY-SA license.&lt;br /&gt;
&lt;br /&gt;
Gavroche is &#039;&#039;currently&#039;&#039; a GNOME3 user. Gavroche uses desktop applications such as &lt;br /&gt;
&lt;br /&gt;
* Blender, for animations and VFX&lt;br /&gt;
* Shotwell/digiKam, for digital photo development&lt;br /&gt;
* GIMP, for photo editing&lt;br /&gt;
* Vim/Emacs/$FOO&lt;br /&gt;
&lt;br /&gt;
Gavroche would like to be able to submit stuff directly from any of these applications, but he should not be required to launch any of them to be able to upload anything.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Desktop application integration is certainly possible sine the API. The main limitation would be the desktop application itself.&amp;lt;/p&amp;gt;&lt;br /&gt;
--[[User:Joar|Joar]] ([[User talk:Joar|talk]]) 07:24, 3 November 2012 (EDT)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Submitting via the web ==&lt;br /&gt;
&lt;br /&gt;
Gavroche uses Firefox or Chromium/Chrome, he might use IE10, but that&#039;s a rare occasion. He avoids IE &amp;lt;= 9 because he has a feeling that they might not be usable everywhere on the web.&lt;br /&gt;
&lt;br /&gt;
Gavroche might have several files, or even a folder of files that he wants to upload. The files might be videos, images, audio, ascii, source files such as .xcf, .blend, etc.&lt;br /&gt;
&lt;br /&gt;
Gavroche drags and drops the files from nautilus to his browser window where the MediaGoblin instance is running.&lt;br /&gt;
&lt;br /&gt;
First he drops the files &#039;&#039;flight.ogv&#039;&#039;, &#039;&#039;superman-wallpaper.png&#039;&#039; and &#039;&#039;swoosh.ogg&#039;&#039; in the browser window, this causes three boxes to be shown to him, each box representing one of the files.&lt;br /&gt;
&lt;br /&gt;
Gavroche then navigates to his project folder for the &#039;&#039;superman-wallpaper.png&#039;&#039; file then selects &#039;&#039;superman-wallpaper.blend&#039;&#039;, &#039;&#039;README.txt&#039;&#039; and &#039;&#039;superman-glasses-texture.png&#039;&#039; then drops them onto the box representing &#039;&#039;superman-wallpaper.png&#039;&#039; in the browser window, this causes three smaller boxes representing each additional file to be shown.&lt;/div&gt;</summary>
		<author><name>Tryggvib</name></author>
	</entry>
	<entry>
		<id>https://wiki.mediagoblin.org/index.php?title=HackingHowto&amp;diff=483</id>
		<title>HackingHowto</title>
		<link rel="alternate" type="text/html" href="https://wiki.mediagoblin.org/index.php?title=HackingHowto&amp;diff=483"/>
		<updated>2012-01-06T12:22:49Z</updated>

		<summary type="html">&lt;p&gt;Tryggvib: /* Fedora / RedHat(?) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Hacking HOWTO =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== So you want to hack on GNU MediaGoblin? ==&lt;br /&gt;
&lt;br /&gt;
First thing to do is check out the [http://mediagoblin.org/join/ web site] where we list all the project&lt;br /&gt;
infrastructure including:&lt;br /&gt;
&lt;br /&gt;
* the IRC channel&lt;br /&gt;
* the mailing list&lt;br /&gt;
* the issue tracker&lt;br /&gt;
&lt;br /&gt;
Additionally, we have information on how to get involved, who to talk&lt;br /&gt;
to, what needs to be worked on, and other things besides!&lt;br /&gt;
&lt;br /&gt;
Second thing to do is take a look at [http://docs.mediagoblin.org/codebase.html codebase chapter] where&lt;br /&gt;
we&#039;ve started documenting how GNU MediaGoblin is built and how to add&lt;br /&gt;
new things.&lt;br /&gt;
&lt;br /&gt;
Third you&#039;ll need to get the requirements.&lt;br /&gt;
&lt;br /&gt;
Fourth, you&#039;ll need to build a development environment.  We use an&lt;br /&gt;
in-package checkout of virtualenv.  This isn&#039;t the convenional way to&lt;br /&gt;
install virtualenv (normally you don&#039;t install virtualenv inside the&lt;br /&gt;
package itself) but we&#039;ve found that it&#039;s significantly easier for&lt;br /&gt;
newcomers who aren&#039;t already familiar with virtualenv.  If you *are*&lt;br /&gt;
already familiar with virtualenv, feel free to just install&lt;br /&gt;
mediagoblin in your own virtualenv setup... the necessary adjustments&lt;br /&gt;
should be obvious.&lt;br /&gt;
&lt;br /&gt;
== Getting requirements ==&lt;br /&gt;
&lt;br /&gt;
First, you need to have the following installed before you can build&lt;br /&gt;
an environment for hacking on GNU MediaGoblin:&lt;br /&gt;
&lt;br /&gt;
* Python 2.6 or 2.7  - http://www.python.org/ (You&#039;ll need Python as well as the dev files for building modules.)&lt;br /&gt;
* python-lxml        - http://lxml.de/&lt;br /&gt;
* git                - http://git-scm.com/&lt;br /&gt;
* MongoDB            - http://www.mongodb.org/&lt;br /&gt;
* Python Imaging Library (PIL) - http://www.pythonware.com/products/pil/&lt;br /&gt;
* virtualenv         - http://www.virtualenv.org/&lt;br /&gt;
* Python GStreamer Bindings - http://gstreamer.freedesktop.org/modules/gst-python.html&lt;br /&gt;
&lt;br /&gt;
Note, MongoDB can get to be pretty huge.  You might want to consider&lt;br /&gt;
looking at [[Scaling Down]] if you are installing this on a smallish&lt;br /&gt;
instance.&lt;br /&gt;
&lt;br /&gt;
=== GNU/Linux ===&lt;br /&gt;
&lt;br /&gt;
==== Debian and derivatives ====&lt;br /&gt;
&lt;br /&gt;
If you&#039;re running Debian GNU/Linux or a Debian-derived distribution&lt;br /&gt;
such as Debian, Mint, or [http://bugs.foocorp.net/issues/478 Ubuntu 10.10+], running the following should install these&lt;br /&gt;
requirements:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|sudo apt-get install mongodb git-core python python-dev python-lxml python-imaging python-virtualenv python-gst0.10}}&lt;br /&gt;
&lt;br /&gt;
==== Fedora / RedHat(?) ====&lt;br /&gt;
&lt;br /&gt;
On Fedora:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|yum install mongodb-server python-paste-deploy python-paste-script git-core python python-devel python-lxml python-imaging python-virtualenv gstreamer-python}}&lt;br /&gt;
&lt;br /&gt;
=== Mac OS X ===&lt;br /&gt;
&lt;br /&gt;
On Mac OS X Lion:&lt;br /&gt;
&lt;br /&gt;
Download the Newest Python.&lt;br /&gt;
&lt;br /&gt;
Git is already installed.&lt;br /&gt;
&lt;br /&gt;
Install MongoDB from these instructions: http://www.mongodb.org/display/DOCS/Quickstart+OS+X&lt;br /&gt;
&lt;br /&gt;
Python-lxml: http://muffinresearch.co.uk/archives/2009/03/05/install-lxml-on-osx/ with sudo&lt;br /&gt;
&lt;br /&gt;
Python Imaging Library (PIL): http://code.google.com/appengine/docs/python/images/installingPIL.html#mac&lt;br /&gt;
&lt;br /&gt;
Libjpeg &amp;amp; Libpng: http://ethan.tira-thompson.org/Mac_OS_X_Ports.html Combo Installer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;You can help:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you have instructions for other GNU/Linux distributions, Windows, or Mac OS X to set&lt;br /&gt;
up requirements, let us know!&lt;br /&gt;
&lt;br /&gt;
== How to set up and maintain an environment for hacking with virtualenv ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
No additional requirements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Create a development environment&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
After installing the requirements, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Clone the repository: {{Cmd|git clone &amp;lt;nowiki&amp;gt;git://gitorious.org/mediagoblin/mediagoblin.git&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
# Change directories to your new checkout: {{Cmd|cd mediagoblin}}&lt;br /&gt;
# Set up the in-package virtualenv: {{Cmd|virtualenv . &amp;amp;&amp;amp; ./bin/python setup.py develop}}&lt;br /&gt;
&lt;br /&gt;
That&#039;s it!&lt;br /&gt;
&lt;br /&gt;
(If you have troubles in the remaining steps, consider try installing&lt;br /&gt;
virtualenv with one of the flags --setuptools, --distribute or possibly --no-site-packages.  Additionally, if your system has python3.X as the default, you might need to do virtualenv --python=python2.7 or --python=python2.6)&lt;br /&gt;
&lt;br /&gt;
If you have problems, please [http://mediagoblin.org/join/ let us know]!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Updating for dependency changes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
While hacking on GNU MediaGoblin over time, you&#039;ll eventually have to&lt;br /&gt;
update your development environment because the dependencies have&lt;br /&gt;
changed.&lt;br /&gt;
&lt;br /&gt;
To do that, run:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|./bin/python setup.py develop --upgrade &amp;amp;&amp;amp; ./bin/gmg migrate}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Updating for code changes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git pull -u}}&lt;br /&gt;
&lt;br /&gt;
== Running Mongo Database ==&lt;br /&gt;
&lt;br /&gt;
Startup the Database if you haven&#039;t already.  On most systems, this&lt;br /&gt;
should be started automatically.  If not, consult the documentation&lt;br /&gt;
for your distribution or the MongoDB docs themselves.&lt;br /&gt;
&lt;br /&gt;
== Running the server ==&lt;br /&gt;
&lt;br /&gt;
If you want to get things running quickly and without hassle, just&lt;br /&gt;
run:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|./lazyserver.sh}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will start up a python server where you can begin playing with&lt;br /&gt;
mediagoblin, listening on 127.0.0.1:6543.  It will also run celery in &amp;quot;always eager&amp;quot; mode so you&lt;br /&gt;
don&#039;t have to start a separate process for it.&lt;br /&gt;
&lt;br /&gt;
By default, the instance is not sending out confirmation mails. Instead they are redirected to the standard output (the console) of lazyserver.sh.&lt;br /&gt;
&lt;br /&gt;
You can change this behavior setting &amp;lt;code&amp;gt;email_debug_mode&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; in mediagoblin.ini&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is fine in development, but if you want to actually run celery&lt;br /&gt;
separately for testing (or deployment purposes), you&#039;ll want to run&lt;br /&gt;
the server independently:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|./bin/paster serve paste.ini --reload}}&lt;br /&gt;
&lt;br /&gt;
== Running celeryd ==&lt;br /&gt;
&lt;br /&gt;
If you aren&#039;t using &amp;lt;tt&amp;gt;./lazyserver.sh&amp;lt;/tt&amp;gt; or otherwise aren&#039;t running celery&lt;br /&gt;
in always eager mode, you&#039;ll need to do this if you want your media to&lt;br /&gt;
process and actually show up.  It&#039;s probably a good idea in&lt;br /&gt;
development to have the web server (above) running in one terminal and&lt;br /&gt;
celeryd in another window.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|&amp;lt;nowiki&amp;gt;CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_celery ./bin/celeryd&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Running the test suite ==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|./runtests.sh}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running a shell ==&lt;br /&gt;
&lt;br /&gt;
If you want a shell with your database pre-setup and an instantiated&lt;br /&gt;
application ready and at your fingertips....&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|./bin/gmg shell}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== pymongo.errors.AutoReconnect: could not find master/primary ===&lt;br /&gt;
&lt;br /&gt;
If you see this:&lt;br /&gt;
&lt;br /&gt;
    pymongo.errors.AutoReconnect: could not find master/primary&lt;br /&gt;
&lt;br /&gt;
then make sure mongodb is installed and running.&lt;br /&gt;
&lt;br /&gt;
If it&#039;s installed, check the mongodb log.  On my machine, that&#039;s &lt;br /&gt;
&amp;lt;tt&amp;gt;/var/log/mongodb/mongodb.log&amp;lt;/tt&amp;gt;.  If you see something like:&lt;br /&gt;
&lt;br /&gt;
    old lock file: /var/lib/mongodb/mongod.lock.  probably means...&lt;br /&gt;
&lt;br /&gt;
in that case you might have had an unclean shutdown.  Try:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|sudo mongod --repair}}&lt;br /&gt;
&lt;br /&gt;
If that didn&#039;t work, just delete the lock file and relaunch mongodb.&lt;br /&gt;
&lt;br /&gt;
Anyway, then start the mongodb server in whatever way is appropriate&lt;br /&gt;
for your distro / OS.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Wiping your user data ==&lt;br /&gt;
&lt;br /&gt;
You can completely wipe all data from the instance by doing:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|gmg wipealldata}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Unless you&#039;re doing development and working on and testing creating&lt;br /&gt;
a new instance, you will probably never have to do this.  Will&lt;br /&gt;
plans to do this work and thus he documented it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Quickstart for Django programmers ==&lt;br /&gt;
&lt;br /&gt;
We&#039;re not using Django, but the codebase is very Django-like in its&lt;br /&gt;
structure.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;routing.py&amp;lt;/tt&amp;gt; is like &amp;lt;tt&amp;gt;urls.py&amp;lt;/tt&amp;gt; in Django&lt;br /&gt;
* &amp;lt;tt&amp;gt;models.py&amp;lt;/tt&amp;gt; has mongokit ORM definitions&lt;br /&gt;
* &amp;lt;tt&amp;gt;views.py&amp;lt;/tt&amp;gt; is where the views go&lt;br /&gt;
&lt;br /&gt;
We&#039;re using MongoDB.  Basically, instead of a relational database with&lt;br /&gt;
tables, you have a big JSON structure which acts a lot like a Python&lt;br /&gt;
dict.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;YouCanHelp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If there are other things that you think would help orient someone&lt;br /&gt;
new to GNU MediaGoblin but coming from Django, let us know!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Bite-sized bugs to start with ==&lt;br /&gt;
&lt;br /&gt;
Now you should visit our latest list of [http://bugs.foocorp.net/projects/mediagoblin/issues?query_id=3 bite-sized issues] because squishing bugs is messy fun. If you&#039;re interested in other things to work on, or need help getting started on a bug, let us know on [http://mediagoblin.org/join/ the mailing list] or on the [http://mediagoblin.org/join/ IRC channel].&lt;/div&gt;</summary>
		<author><name>Tryggvib</name></author>
	</entry>
	<entry>
		<id>https://wiki.mediagoblin.org/index.php?title=HackingHowto&amp;diff=482</id>
		<title>HackingHowto</title>
		<link rel="alternate" type="text/html" href="https://wiki.mediagoblin.org/index.php?title=HackingHowto&amp;diff=482"/>
		<updated>2012-01-06T00:41:39Z</updated>

		<summary type="html">&lt;p&gt;Tryggvib: /* Getting requirements */ Added Python GStreamer bindings&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Hacking HOWTO =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== So you want to hack on GNU MediaGoblin? ==&lt;br /&gt;
&lt;br /&gt;
First thing to do is check out the [http://mediagoblin.org/join/ web site] where we list all the project&lt;br /&gt;
infrastructure including:&lt;br /&gt;
&lt;br /&gt;
* the IRC channel&lt;br /&gt;
* the mailing list&lt;br /&gt;
* the issue tracker&lt;br /&gt;
&lt;br /&gt;
Additionally, we have information on how to get involved, who to talk&lt;br /&gt;
to, what needs to be worked on, and other things besides!&lt;br /&gt;
&lt;br /&gt;
Second thing to do is take a look at [http://docs.mediagoblin.org/codebase.html codebase chapter] where&lt;br /&gt;
we&#039;ve started documenting how GNU MediaGoblin is built and how to add&lt;br /&gt;
new things.&lt;br /&gt;
&lt;br /&gt;
Third you&#039;ll need to get the requirements.&lt;br /&gt;
&lt;br /&gt;
Fourth, you&#039;ll need to build a development environment.  We use an&lt;br /&gt;
in-package checkout of virtualenv.  This isn&#039;t the convenional way to&lt;br /&gt;
install virtualenv (normally you don&#039;t install virtualenv inside the&lt;br /&gt;
package itself) but we&#039;ve found that it&#039;s significantly easier for&lt;br /&gt;
newcomers who aren&#039;t already familiar with virtualenv.  If you *are*&lt;br /&gt;
already familiar with virtualenv, feel free to just install&lt;br /&gt;
mediagoblin in your own virtualenv setup... the necessary adjustments&lt;br /&gt;
should be obvious.&lt;br /&gt;
&lt;br /&gt;
== Getting requirements ==&lt;br /&gt;
&lt;br /&gt;
First, you need to have the following installed before you can build&lt;br /&gt;
an environment for hacking on GNU MediaGoblin:&lt;br /&gt;
&lt;br /&gt;
* Python 2.6 or 2.7  - http://www.python.org/ (You&#039;ll need Python as well as the dev files for building modules.)&lt;br /&gt;
* python-lxml        - http://lxml.de/&lt;br /&gt;
* git                - http://git-scm.com/&lt;br /&gt;
* MongoDB            - http://www.mongodb.org/&lt;br /&gt;
* Python Imaging Library (PIL) - http://www.pythonware.com/products/pil/&lt;br /&gt;
* virtualenv         - http://www.virtualenv.org/&lt;br /&gt;
* Python GStreamer Bindings - http://gstreamer.freedesktop.org/modules/gst-python.html&lt;br /&gt;
&lt;br /&gt;
Note, MongoDB can get to be pretty huge.  You might want to consider&lt;br /&gt;
looking at [[Scaling Down]] if you are installing this on a smallish&lt;br /&gt;
instance.&lt;br /&gt;
&lt;br /&gt;
=== GNU/Linux ===&lt;br /&gt;
&lt;br /&gt;
==== Debian and derivatives ====&lt;br /&gt;
&lt;br /&gt;
If you&#039;re running Debian GNU/Linux or a Debian-derived distribution&lt;br /&gt;
such as Debian, Mint, or [http://bugs.foocorp.net/issues/478 Ubuntu 10.10+], running the following should install these&lt;br /&gt;
requirements:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|sudo apt-get install mongodb git-core python python-dev python-lxml python-imaging python-virtualenv python-gst0.10}}&lt;br /&gt;
&lt;br /&gt;
==== Fedora / RedHat(?) ====&lt;br /&gt;
&lt;br /&gt;
On Fedora:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|yum install mongodb-server python-paste-deploy python-paste-script git-core python python-devel python-lxml python-imaging python-virtualenv}}&lt;br /&gt;
&lt;br /&gt;
=== Mac OS X ===&lt;br /&gt;
&lt;br /&gt;
On Mac OS X Lion:&lt;br /&gt;
&lt;br /&gt;
Download the Newest Python.&lt;br /&gt;
&lt;br /&gt;
Git is already installed.&lt;br /&gt;
&lt;br /&gt;
Install MongoDB from these instructions: http://www.mongodb.org/display/DOCS/Quickstart+OS+X&lt;br /&gt;
&lt;br /&gt;
Python-lxml: http://muffinresearch.co.uk/archives/2009/03/05/install-lxml-on-osx/ with sudo&lt;br /&gt;
&lt;br /&gt;
Python Imaging Library (PIL): http://code.google.com/appengine/docs/python/images/installingPIL.html#mac&lt;br /&gt;
&lt;br /&gt;
Libjpeg &amp;amp; Libpng: http://ethan.tira-thompson.org/Mac_OS_X_Ports.html Combo Installer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;You can help:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you have instructions for other GNU/Linux distributions, Windows, or Mac OS X to set&lt;br /&gt;
up requirements, let us know!&lt;br /&gt;
&lt;br /&gt;
== How to set up and maintain an environment for hacking with virtualenv ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
No additional requirements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Create a development environment&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
After installing the requirements, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Clone the repository: {{Cmd|git clone &amp;lt;nowiki&amp;gt;git://gitorious.org/mediagoblin/mediagoblin.git&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
# Change directories to your new checkout: {{Cmd|cd mediagoblin}}&lt;br /&gt;
# Set up the in-package virtualenv: {{Cmd|virtualenv . &amp;amp;&amp;amp; ./bin/python setup.py develop}}&lt;br /&gt;
&lt;br /&gt;
That&#039;s it!&lt;br /&gt;
&lt;br /&gt;
(If you have troubles in the remaining steps, consider try installing&lt;br /&gt;
virtualenv with one of the flags --setuptools, --distribute or possibly --no-site-packages.  Additionally, if your system has python3.X as the default, you might need to do virtualenv --python=python2.7 or --python=python2.6)&lt;br /&gt;
&lt;br /&gt;
If you have problems, please [http://mediagoblin.org/join/ let us know]!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Updating for dependency changes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
While hacking on GNU MediaGoblin over time, you&#039;ll eventually have to&lt;br /&gt;
update your development environment because the dependencies have&lt;br /&gt;
changed.&lt;br /&gt;
&lt;br /&gt;
To do that, run:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|./bin/python setup.py develop --upgrade &amp;amp;&amp;amp; ./bin/gmg migrate}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Updating for code changes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git pull -u}}&lt;br /&gt;
&lt;br /&gt;
== Running Mongo Database ==&lt;br /&gt;
&lt;br /&gt;
Startup the Database if you haven&#039;t already.  On most systems, this&lt;br /&gt;
should be started automatically.  If not, consult the documentation&lt;br /&gt;
for your distribution or the MongoDB docs themselves.&lt;br /&gt;
&lt;br /&gt;
== Running the server ==&lt;br /&gt;
&lt;br /&gt;
If you want to get things running quickly and without hassle, just&lt;br /&gt;
run:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|./lazyserver.sh}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will start up a python server where you can begin playing with&lt;br /&gt;
mediagoblin, listening on 127.0.0.1:6543.  It will also run celery in &amp;quot;always eager&amp;quot; mode so you&lt;br /&gt;
don&#039;t have to start a separate process for it.&lt;br /&gt;
&lt;br /&gt;
By default, the instance is not sending out confirmation mails. Instead they are redirected to the standard output (the console) of lazyserver.sh.&lt;br /&gt;
&lt;br /&gt;
You can change this behavior setting &amp;lt;code&amp;gt;email_debug_mode&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; in mediagoblin.ini&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is fine in development, but if you want to actually run celery&lt;br /&gt;
separately for testing (or deployment purposes), you&#039;ll want to run&lt;br /&gt;
the server independently:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|./bin/paster serve paste.ini --reload}}&lt;br /&gt;
&lt;br /&gt;
== Running celeryd ==&lt;br /&gt;
&lt;br /&gt;
If you aren&#039;t using &amp;lt;tt&amp;gt;./lazyserver.sh&amp;lt;/tt&amp;gt; or otherwise aren&#039;t running celery&lt;br /&gt;
in always eager mode, you&#039;ll need to do this if you want your media to&lt;br /&gt;
process and actually show up.  It&#039;s probably a good idea in&lt;br /&gt;
development to have the web server (above) running in one terminal and&lt;br /&gt;
celeryd in another window.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|&amp;lt;nowiki&amp;gt;CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_celery ./bin/celeryd&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Running the test suite ==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|./runtests.sh}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running a shell ==&lt;br /&gt;
&lt;br /&gt;
If you want a shell with your database pre-setup and an instantiated&lt;br /&gt;
application ready and at your fingertips....&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|./bin/gmg shell}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== pymongo.errors.AutoReconnect: could not find master/primary ===&lt;br /&gt;
&lt;br /&gt;
If you see this:&lt;br /&gt;
&lt;br /&gt;
    pymongo.errors.AutoReconnect: could not find master/primary&lt;br /&gt;
&lt;br /&gt;
then make sure mongodb is installed and running.&lt;br /&gt;
&lt;br /&gt;
If it&#039;s installed, check the mongodb log.  On my machine, that&#039;s &lt;br /&gt;
&amp;lt;tt&amp;gt;/var/log/mongodb/mongodb.log&amp;lt;/tt&amp;gt;.  If you see something like:&lt;br /&gt;
&lt;br /&gt;
    old lock file: /var/lib/mongodb/mongod.lock.  probably means...&lt;br /&gt;
&lt;br /&gt;
in that case you might have had an unclean shutdown.  Try:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|sudo mongod --repair}}&lt;br /&gt;
&lt;br /&gt;
If that didn&#039;t work, just delete the lock file and relaunch mongodb.&lt;br /&gt;
&lt;br /&gt;
Anyway, then start the mongodb server in whatever way is appropriate&lt;br /&gt;
for your distro / OS.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Wiping your user data ==&lt;br /&gt;
&lt;br /&gt;
You can completely wipe all data from the instance by doing:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|gmg wipealldata}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Unless you&#039;re doing development and working on and testing creating&lt;br /&gt;
a new instance, you will probably never have to do this.  Will&lt;br /&gt;
plans to do this work and thus he documented it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Quickstart for Django programmers ==&lt;br /&gt;
&lt;br /&gt;
We&#039;re not using Django, but the codebase is very Django-like in its&lt;br /&gt;
structure.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;routing.py&amp;lt;/tt&amp;gt; is like &amp;lt;tt&amp;gt;urls.py&amp;lt;/tt&amp;gt; in Django&lt;br /&gt;
* &amp;lt;tt&amp;gt;models.py&amp;lt;/tt&amp;gt; has mongokit ORM definitions&lt;br /&gt;
* &amp;lt;tt&amp;gt;views.py&amp;lt;/tt&amp;gt; is where the views go&lt;br /&gt;
&lt;br /&gt;
We&#039;re using MongoDB.  Basically, instead of a relational database with&lt;br /&gt;
tables, you have a big JSON structure which acts a lot like a Python&lt;br /&gt;
dict.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;YouCanHelp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If there are other things that you think would help orient someone&lt;br /&gt;
new to GNU MediaGoblin but coming from Django, let us know!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Bite-sized bugs to start with ==&lt;br /&gt;
&lt;br /&gt;
Now you should visit our latest list of [http://bugs.foocorp.net/projects/mediagoblin/issues?query_id=3 bite-sized issues] because squishing bugs is messy fun. If you&#039;re interested in other things to work on, or need help getting started on a bug, let us know on [http://mediagoblin.org/join/ the mailing list] or on the [http://mediagoblin.org/join/ IRC channel].&lt;/div&gt;</summary>
		<author><name>Tryggvib</name></author>
	</entry>
	<entry>
		<id>https://wiki.mediagoblin.org/index.php?title=OStatus&amp;diff=407</id>
		<title>OStatus</title>
		<link rel="alternate" type="text/html" href="https://wiki.mediagoblin.org/index.php?title=OStatus&amp;diff=407"/>
		<updated>2011-11-14T12:40:42Z</updated>

		<summary type="html">&lt;p&gt;Tryggvib: Created a page with information about OStatus (how to publish through OStatus to begin with)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= OStatus =&lt;br /&gt;
&lt;br /&gt;
OStatus is, as described on its [http://ostatus.org official site]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;an open standard for distributed status updates. [The] goal is a specification that allows different messaging hubs to route status updates between users in near-real-time-&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Important Links ==&lt;br /&gt;
&lt;br /&gt;
* http://ostatus.org/&lt;br /&gt;
* http://ostatus.org/sites/default/files/ostatus-1.0-draft-2-specification.html&lt;br /&gt;
&lt;br /&gt;
== Process and work products ==&lt;br /&gt;
&lt;br /&gt;
Process based on: http://ostatus.org/2010/10/04/how-ostatus-enable-your-application&lt;br /&gt;
&lt;br /&gt;
* Activity Streams, can be broken into:&lt;br /&gt;
** Provide Atom feed&lt;br /&gt;
** Transform Atom feed into activity stream&lt;br /&gt;
* PubSubHubbub Publish, can be broken into:&lt;br /&gt;
** Decide on and declare hub in user activity streams&lt;br /&gt;
** Publish to hub when activity entries are created&lt;br /&gt;
* WebFinger, can be broken into:&lt;br /&gt;
** Provide host-meta file for site with user account template url&lt;br /&gt;
** Provide account information for specific users&lt;br /&gt;
&lt;br /&gt;
When a federated site has PUSH-enabled ActivityStreams, users on remote services can subscribe to users on the federated site and be notified when their status updates.&lt;br /&gt;
&lt;br /&gt;
== ActivityStreams ==&lt;br /&gt;
&lt;br /&gt;
ActivityStreams is a standardized way to represent activities of individual users on social sites. It is nothing more than an atom feed with additions to further categorize the activity entries. Each activity entry &#039;&#039;does something&#039;&#039; to an activity object.&lt;br /&gt;
&lt;br /&gt;
This is the core of the social interactions which the OStatus standard makes distributable across multiple federated sites.&lt;br /&gt;
&lt;br /&gt;
=== How to Implement ===&lt;br /&gt;
&lt;br /&gt;
For an example use case, lets say that we have a running MediaGoblin instance on &#039;&#039;mediagoblin.server.com&#039;&#039; and we want to provide an ActivityStream for a user with a username &#039;&#039;yooser&#039;&#039; at a specific location, e.g. http://mediagoblin.server.com/u/yooser/as.atom &lt;br /&gt;
&lt;br /&gt;
The first thing we have to do is create an Atom feed for yooser. This is relatively simple to do in Django and shouldn&#039;t be much of a problem in MediaGoblin&#039;s framework. We must keep in mind that we will have to expand the feed with additional information. We should make the atom feed discoverable using a link from the user&#039;s profile page: &amp;lt;link rel=&amp;quot;alternate&amp;quot; href=&amp;quot;http://mediagoblin.server.com/u/yooser/as.atom&amp;quot; type=&amp;quot;application/atom+xml&amp;quot; title=&amp;quot;Atom feed for yooser&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next step is to choose what a user can do and which objects the user can do it onto. This is a really big deal and should be carefully chosen. The implementation of what gets chosen should be done in such a way that it enables easy additions to the entries and objects.&lt;br /&gt;
&lt;br /&gt;
So, lets start with the activity objects of the system. There are a lot of them to choose from and not all of them have to be implemented (for example, why should MediaGoblin do anything about article, i.e. blog posts). Here&#039;s the complete list of object types according to the Activity Base Schema Draft (yes, it&#039;s not final):&lt;br /&gt;
&lt;br /&gt;
* Article - A lot of paragraphs of text which might incorporate images and stuff&lt;br /&gt;
* Audio - File containing songs, speech or just about anything somebody can listen to&lt;br /&gt;
* Badge - Some sort of an award which can be granted to somebody&lt;br /&gt;
* Bookmark - Basically just a link to a website, called bookmark to avoid confusion&lt;br /&gt;
* Collection - A generic container for a lot of objects, like an album of photos or folders of files&lt;br /&gt;
* Comment - A text response to another object &lt;br /&gt;
* Event - Description of a &amp;quot;happening&amp;quot; which people can attend at some location at a specific time&lt;br /&gt;
* File - A generic document which cannot be categorized as anything specific (like Audio, Image or Video)&lt;br /&gt;
* Group - Similar to collection but allows member objects to join or leave&lt;br /&gt;
* Image - File containing something stationary which can be perceived through eye (or something else)&lt;br /&gt;
* Note - A dent, tweet, status update or any other form of short, only content article-ish object&lt;br /&gt;
* Person - A user on the system (or on another system) - core thing really&lt;br /&gt;
* Place - The draft says it best: &#039;The &amp;quot;place&amp;quot; object type represents a location on Earth.&#039;&lt;br /&gt;
* Product - Some object or act which people sell or offer in return for something, like a book&lt;br /&gt;
* Question - A way to get opinion from others. A poll.&lt;br /&gt;
* Review - A (hopefully) well formed written opinion about what somebody thinks about something&lt;br /&gt;
* Service - Not to be confused with service as in product but a blog or something that services others&lt;br /&gt;
* Video - A file containing a lot of images in sequence, and in most cases combined with audio&lt;br /&gt;
&lt;br /&gt;
There are also some extensions to this base schema described in the draft. These extensions can be added to the other objects but don&#039;t describe anything purely on their own (well they do but theoretically let&#039;s just say that it wouldn&#039;t make sense):&lt;br /&gt;
&lt;br /&gt;
* Location - A place object which describes where some other object is at&lt;br /&gt;
* Mood - An object which describes in what mood the creator was or a person is in&lt;br /&gt;
* Rating - A number between 1.0 and 5.0 (with one decimal place)... think stars!&lt;br /&gt;
* Source - The original place where something came from, don&#039;t go all the way back to The Big Bang!&lt;br /&gt;
* Tags - A list of objects which have been marked as a part of something, like a person in a picture&lt;br /&gt;
&lt;br /&gt;
The same schema defines what can be done with these objects. &lt;br /&gt;
&lt;br /&gt;
* add - something is being added to something (a photo to an album)&lt;br /&gt;
* cancel - something is cancelled (an event)&lt;br /&gt;
* checkin - something/someone has arrived at a place&lt;br /&gt;
* delete - something has been deleted (does not necessarily mean permanent destruction)&lt;br /&gt;
* favorite - something/someone really, really likes something (favorite video/status)&lt;br /&gt;
* follow - someone/something started following the activity stream of someone/something&lt;br /&gt;
* give - someone/something gives something (like a badge) to someone/something&lt;br /&gt;
* ignore - someone/something ignores something&lt;br /&gt;
* invite - someone/something invites someone/something to something&lt;br /&gt;
* join - someone/something joins something&lt;br /&gt;
* leave - inverse of join or the inverse of checkin (someone/something leaves something)&lt;br /&gt;
* like - another form of favorite&lt;br /&gt;
* make-friend - a verb that says friendship has been formed&lt;br /&gt;
* play - something is played (a video)&lt;br /&gt;
* post - creation of an object&lt;br /&gt;
* receive - someone or something has received something (like a badge)&lt;br /&gt;
* remove - something is removed from something (a photo from an album)&lt;br /&gt;
* remove-friend - friendship has been discontinued&lt;br /&gt;
* request-friend - someone wants to become friends with someone&lt;br /&gt;
* rsvp-maybe - someone might attend something (an event)&lt;br /&gt;
* rsvp-no - someone won&#039;t attend something (an event)&lt;br /&gt;
* rsvp-yes - someone will attend something (an event)&lt;br /&gt;
* save - someone has saved something out of personal interest&lt;br /&gt;
* share - something is shared with others&lt;br /&gt;
* stop-following - someone/something has stopped following the activity stream of something&lt;br /&gt;
* tag - someone/something is said to be present in something&lt;br /&gt;
* unfavorite - something is not as awesome as it once was&lt;br /&gt;
* unlike - something is not as ok as it once was&lt;br /&gt;
* unsave - something is not being used for personal interest anymore&lt;br /&gt;
* update - something has been updated (a blog post)&lt;br /&gt;
&lt;br /&gt;
So, now we know what we can do and what we can do it onto. For MediaGoblin we should choose a subset of these objects and activity verbs. Let&#039;s start with the objects. MediaGoblin is a site primarily to be used for sharing and socializing around media. As such we need media objects and a few other objects make these media objects sociable. Of course MediaGoblin could in the future incorporate other activity objects (like organizing events or give out badges) but let&#039;s restrict us to pure media socializing.&lt;br /&gt;
&lt;br /&gt;
Firstly, we need the core thing... the user:&lt;br /&gt;
&lt;br /&gt;
* Person - A user of the system represented as an activity object&lt;br /&gt;
&lt;br /&gt;
Secondly, these are the media types:&lt;br /&gt;
&lt;br /&gt;
* Image - Users should be able to upload and view photos and other images&lt;br /&gt;
* Audio - Users should be able to upload and listen to audio files&lt;br /&gt;
* Video - Users should be able to upload and watch videos&lt;br /&gt;
* File - Users should be able to upload and download other files (e.g. README documents, books)&lt;br /&gt;
&lt;br /&gt;
Lastly, we need to allow other object types to make MediaGoblin social:&lt;br /&gt;
&lt;br /&gt;
* Collection - To create an album of videos or images (thus allowing categorization)&lt;br /&gt;
* Group - To allow users to find users and media more easily (find and categorize people/media objects)&lt;br /&gt;
* Comment - To allow users to comment on media files (their own or uploaded by others)&lt;br /&gt;
* Place - To describe a location (a place shown in an image)&lt;br /&gt;
&lt;br /&gt;
We should also allow a few extensions to the base schema:&lt;br /&gt;
&lt;br /&gt;
* Location - The reason we allowed Place&lt;br /&gt;
* Source - To attribute the right author&lt;br /&gt;
* Tags - To tag a place or a person in a media object&lt;br /&gt;
&lt;br /&gt;
Now we need to decide what verbs the person (actor) can perform. Regarding favorite or like, we should go with favorite to avoid any confusion around Facebook. The following list also assumes a Status.Net approach (anybody can follow anybody, instead of creating friendship). It also does not include play, just because I (the one who wrote this) doesn&#039;t like other people knowing what I&#039;m doing in such detail.&lt;br /&gt;
&lt;br /&gt;
* post, delete - To create or destroy media objects (delete should permanently delete stuff)&lt;br /&gt;
* add, remove - To add or remove media objects from albums (collection)&lt;br /&gt;
* favorite, unfavorite - To allow other persons to see what one person thinks is awesome&lt;br /&gt;
* follow, stop-following - To allow persons to add other persons to their stream&lt;br /&gt;
* join, leave - To allow someone to join/leave a group about some specific topic&lt;br /&gt;
* share - To allow a person to redistribute a media object from another person on that person&#039;s stream&lt;br /&gt;
* tag - To allow a person to say that another person is in a media object&lt;br /&gt;
&lt;br /&gt;
OK. So how do we do it? Each and every activity object described above includes specific information which is only used for that specific object. One way to form the objects is to create an activity object model class (e.g. ActivityConstruct) which can be subclassed as a specific activity object. Each subclassed activity object then has a method (e.g. def ostatus(self)) which can be called to get the object type and the corresponding information. The activity itself (using a verb on an object) is then collected in another model, e.g. ActivityEntry which forms the timeline (the activity stream). Defining the ActivityEntry model in Django would then be something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
class ActivityEntry(models.Model):&lt;br /&gt;
    atom_id = models.CharField(max_length=256, editable=False) # unique id, using uuid1()&lt;br /&gt;
    actor = models.ForeignKey(&#039;Person&#039;, related_name=&#039;actors&#039;) # &lt;br /&gt;
    activityobject = models.ForeignKey(&#039;ActivityConstruct&#039;, related_name=&#039;activity_objects&#039;)&lt;br /&gt;
    target = models.ForeignKey(&#039;ActivityConstruct&#039;, blank=True, null=True, related_name=&#039;activity_targets&#039;)&lt;br /&gt;
    verb = models.CharField(max_length=128)&lt;br /&gt;
    time = models.DateTimeField(auto_now_add=True)&lt;br /&gt;
    title = models.CharField(max_length=256) # Short description (usually same as summary)&lt;br /&gt;
    summary = models.TextField() # &amp;lt;person&amp;gt; &amp;lt;verb&amp;gt;ed &amp;lt;activityobject&amp;gt; (in &amp;lt;target&amp;gt;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The problem with this approach (i.e. in Django) is how to access the subclasses since the activity entry points to the parent class. It&#039;s messy but is still a good way to achieve this. MediaGoblin&#039;s framework might be able to solve this in a better way.&lt;br /&gt;
&lt;br /&gt;
All right. So, how do we show it? Well, we take our Atom feed (which would represent the timeline of activity entries) and append stuff to it. For a regular atom feed an &amp;lt;entry&amp;gt; element consists of the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;entry&amp;gt;&lt;br /&gt;
  &amp;lt;id&amp;gt;urn:uuid:11bba138-0eb3-11e1-ba8a-13b887ad42f8&amp;lt;/id&amp;gt;&lt;br /&gt;
  &amp;lt;title&amp;gt;yooser posted a video&amp;lt;/title&amp;gt;&lt;br /&gt;
  &amp;lt;link rel=&amp;quot;alternate&amp;quot; type=&amp;quot;text/html&amp;quot; href=&amp;quot;http://mediagoblin.server.com/u/yooser/gallery/himom.ogv&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;link rel=&amp;quot;self&amp;quot; type=&amp;quot;application/atom+xml&amp;quot; href=&amp;quot;http://mediagoblin.server.com/u/yooser/111113112602.atom&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;published&amp;gt;2011-11-13T11:26:02Z&amp;lt;/published&amp;gt;&lt;br /&gt;
  &amp;lt;summary&amp;gt;yooser just uploaded a brand new video&amp;lt;/summary&amp;gt;&lt;br /&gt;
&amp;lt;/entry&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adding activity stream stuff is just about adding the relevant information. Video information is for example: author (can be omitted if the author is the actor), displayName (title of video), embedCode (code for HTML embedding), id (unique id for video), published (optional time when published), stream (media link to video, summary (optional summary of video), updated (optional time when updated). For unique id&#039;s we use uuid1 (simple and easy to create). The resulting &amp;lt;entry&amp;gt; element would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;entry&amp;gt;&lt;br /&gt;
  &amp;lt;id&amp;gt;urn:uuid:11bba138-0eb3-11e1-ba8a-13b887ad42f8&amp;lt;/id&amp;gt;&lt;br /&gt;
  &amp;lt;title&amp;gt;yooser posted a video&amp;lt;/title&amp;gt;&lt;br /&gt;
  &amp;lt;published&amp;gt;2011-11-13T11:26:02Z&amp;lt;/published&amp;gt;&lt;br /&gt;
  &amp;lt;summary&amp;gt;yooser just uploaded a brand new video&amp;lt;/summary&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;activity:object&amp;gt;&lt;br /&gt;
  &amp;lt;activity:object-type&amp;gt;http://activitystrea.ms/schema/1.0/video&amp;lt;/activity:object-type&amp;gt;&lt;br /&gt;
  &amp;lt;id&amp;gt;urn:uuid:02b0a5ce-0eba-11e1-ba8a-13b887ad42f8&amp;lt;/id&amp;gt;&lt;br /&gt;
  &amp;lt;activity:displayName&amp;gt;Hi Mom!&amp;lt;/activity:displayName&amp;gt;&lt;br /&gt;
  &amp;lt;activity:embedCode&amp;gt;&lt;br /&gt;
&amp;amp;lt;video width=&amp;amp;quot;320&amp;amp;quot; height=&amp;amp;quot;240&amp;amp;quot; controls&amp;amp;gt;&amp;amp;lt;source src=&amp;amp;quot;http://mediagoblin.server.com/u/yooser/gallery/himom.ogv&amp;amp;quot; type=&#039;video/ogg; codecs=&amp;amp;quot;theora, vorbis&amp;amp;quot;&#039;&amp;amp;gt;&amp;amp;lt;source src=&amp;amp;quot;http://mediagoblin.server.com/u/yooser/gallery/himom.webm&amp;amp;quot; type=&#039;video/webm; codecs=&amp;amp;quot;vp8, vorbis&amp;amp;quot;&#039;&amp;amp;gt;&amp;amp;lt;source src=&amp;amp;quot;http://mediagoblin.server.com/u/yooser/gallery/himom.mp4&amp;amp;quot; type=&#039;video/mp4; codecs=&amp;amp;quot;avc1.42E01E, mp4a.40.2&amp;amp;quot;&#039;&amp;amp;gt;&amp;amp;lt;/video&amp;amp;gt;&amp;lt;/activity:embedCode&amp;gt;&lt;br /&gt;
  &amp;lt;activity:stream&amp;gt;http://mediagoblin.server.com/u/yooser/gallery/himom.ogv&amp;lt;/activity:stream&amp;gt;&lt;br /&gt;
  &amp;lt;summary&amp;gt;I wave my hands and yell: Hi Mom!&amp;lt;/summary&amp;gt;&lt;br /&gt;
  &amp;lt;/activity:object&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;activity:verb&amp;gt;http://activitystrea.ms/schema/1.0/post&amp;lt;/activity:verb&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;link rel=&amp;quot;alternate&amp;quot; type=&amp;quot;text/html&amp;quot; href=&amp;quot;http://mediagoblin.server.com/u/yooser/111113112602/&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;link rel=&amp;quot;self&amp;quot; type=&amp;quot;application/atom+xml&amp;quot; href=&amp;quot;http://mediagoblin.server.com/u/yooser/111113112602.atom&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/entry&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The activity namespace is declared as &amp;quot;http://activitystrea.ms/spec/1.0/&amp;quot;. These additions are really easy since we only need to look at the [http://activitystrea.ms/head/activity-schema.html activity stream basic schema] and see what we need to include for each one of the object types we use. It is well defined their. Then we create a function to provide this information (optimally to provide the atom representation of it).&lt;br /&gt;
&lt;br /&gt;
We also have to declare the author in the feed and since it is a part of Atom already we only have to add a few things. The [http://ostatus.org/2010/10/04/how-ostatus-enable-your-application blog post] adds to optional choices. First recommendation is adding extra information using links, like e.g. the user avatar. The second recommendation is using Portable Contacts. These two are not a part of the OStatus standard but could be good additions. Let&#039;s say for clarity that we skip both of them and define the author as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;author&amp;gt;&lt;br /&gt;
 &amp;lt;activity:object-type&amp;gt;http://activitystrea.ms/schema/1.0/person&amp;lt;/activity:object-type&amp;gt;&lt;br /&gt;
 &amp;lt;uri&amp;gt;http://mediagoblin.server.com/u/yooser/&amp;lt;/uri&amp;gt;&lt;br /&gt;
 &amp;lt;name&amp;gt;yooser&amp;lt;/name&amp;gt;&lt;br /&gt;
&amp;lt;/author&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is quite a lot of work but it should be relatively straightforward to do. Create the atom feed. Create the media objects (but first think really hard about the model structure). Create a good way to create atom representations. Add to Atom feed. Test.&lt;br /&gt;
&lt;br /&gt;
=== Related Links ===&lt;br /&gt;
&lt;br /&gt;
* http://activitystrea.ms/&lt;br /&gt;
* http://activitystrea.ms/head/activity-schema.html&lt;br /&gt;
* http://atomenabled.org/&lt;br /&gt;
* http://portablecontacts.net/&lt;br /&gt;
&lt;br /&gt;
== PubSubHubbub Publish ==&lt;br /&gt;
&lt;br /&gt;
PubSubHubbub (PuSH) avoids polling for updates by creating a place (hub) where content providers publish (pub) their updates and the hub then takes care of notifying the those who have subscribed (sub) to their feeds. It&#039;s a simple approach which involves using regular HTTP POSTs.&lt;br /&gt;
&lt;br /&gt;
OStatus uses this to allow users on other federated services to subscribe to activity streams on another service without having to put an extra polling load on the services with the subscribers.&lt;br /&gt;
&lt;br /&gt;
=== How to Implement ===&lt;br /&gt;
 &lt;br /&gt;
For an example use case, lets say that we have a running MediaGoblin instance on &#039;&#039;mediagoblin.server.com&#039;&#039; and we want to publish the activity streams of our users to a given pubsubhubbub service. This must be a configurable variable for those who want to set up MediaGoblin instances (since they should be free to choose which services they use) but the official MediaGoblin might run its own hub which would be provided by default to make MediaGoblin instance creations simpler. There are a lot of different hub implementations available which could be used. This could also be a configurable variable for each user but that would just make MediaGoblin more difficult to use.&lt;br /&gt;
&lt;br /&gt;
For the sake of example, let&#039;s say the instance on &#039;&#039;mediagoblin.server.com&#039;&#039; is set to use a hub located at: &#039;&#039;http://pubsubhub.bub.com&#039;&#039;. Every Atom activity stream on the MediaGoblin server must then provide a link element (marked with a rel attribute &amp;quot;hub&amp;quot;) pointing to the PuSH server, so we add &amp;lt;link href=&amp;quot;http://pubsubhub.bub.com&amp;quot; rel=&amp;quot;hub&amp;quot;/&amp;gt; to the Atom feed.&lt;br /&gt;
&lt;br /&gt;
It is not as important but a common web feed courtesy not to forget a properly set link with self as a rel value (expressing where the feed is). So if we are trying to publish the activity stream of a user called yooser which is located at http://mediagoblin.server.com/u/yooser/as.atom we add the self link in the atom feed with &amp;lt;link rel=&amp;quot;self&amp;quot; type=&amp;quot;application/atom+xml&amp;quot; href=&amp;quot;http://mediagoblin.server.com/u/yooser/as.atom&amp;quot; /&amp;gt;. This should be taken care of by the framework but lets be sure.&lt;br /&gt;
&lt;br /&gt;
Next step. When a new activity stream is created or an existing one updated, we need to publish it to the hub. It&#039;s a really simple POST operation. We need to encode two variables, &#039;&#039;hub.url&#039;&#039; and &#039;&#039;hub.mode&#039;&#039;. The hub.url should contain the URL to the activity stream being published, which would in the case of our user &#039;&#039;yooser&#039;&#039; be http://mediagoblin.server.com/u/yooser/as.atom and the hub.mode must contain a single word: &#039;publish&#039;. If the POSTing to the hub is successful the hub will return a 204 error code (No Content). If something goes wrong, the hub will return an appropriate error code.&lt;br /&gt;
&lt;br /&gt;
In Python this is quite easy to do using urllib and urllib2:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
hub = &#039;http://pubsubhub.bub.com&#039;&lt;br /&gt;
url = &#039;http://mediagoblin.server.com/u/yooser/as.atom&#039;&lt;br /&gt;
&lt;br /&gt;
data = urllib.urlencode({&#039;hub.url&#039;:url, &#039;hub.mode&#039;:&#039;publish&#039;})&lt;br /&gt;
try:&lt;br /&gt;
    response = urllib2.urlopen(hub, data)&lt;br /&gt;
except (IOError, urllib2.HTTPError), e:&lt;br /&gt;
    if hasattr(e, &#039;code&#039;) and e.code == 204:&lt;br /&gt;
        print &#039;Successfully published to hub&#039;&lt;br /&gt;
    else:&lt;br /&gt;
        print &#039;Gosh darn it Spencer! It failed!&#039;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example does not bother with error handling (except to check status code), wrapping it in a function and it uses hard coded values, all for the sake of clarity. A better example is available from the [http://code.google.com/p/pubsubhubbub/source/browse/trunk/publisher_clients/python/pubsubhubbub_publish.py pubsubhubbub source repository] under the Apache license.&lt;br /&gt;
&lt;br /&gt;
=== Related Links ===&lt;br /&gt;
&lt;br /&gt;
* http://code.google.com/p/pubsubhubbub/&lt;br /&gt;
* http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.3.html&lt;br /&gt;
* http://code.google.com/p/pubsubhubbub/source/browse/trunk/publisher_clients/python/pubsubhubbub_publish.py (Apache License)&lt;br /&gt;
&lt;br /&gt;
== WebFinger ==&lt;br /&gt;
&lt;br /&gt;
WebFinger is a way to identify users by email addresses and allow sites to access more information about the specific user. To accomplish this WebFinger uses two resources: &#039;&#039;A domain specific host-meta file&#039;&#039; which contains information about how to access information about a specific user, and the individual user description files, called endpoints. Both of these resources are relatively simple XRD documents.&lt;br /&gt;
&lt;br /&gt;
OStatus uses this to allow different federated sites with different routing structures to find the activity streams of users (and perhaps other information as well) easily.&lt;br /&gt;
&lt;br /&gt;
=== How to Implement ===&lt;br /&gt;
&lt;br /&gt;
For an example use case, lets say that we have a running MediaGoblin instance on &#039;&#039;mediagoblin.server.com&#039;&#039; and we want to provide WebFinger identities for our users and in our example case a user with a username &#039;&#039;yooser&#039;&#039;. This user would get the WebFinger identity (email): &#039;&#039;yooser@mediagoblin.server.com&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The MediaGoblin instance will have to set up a host-meta file and make it available at: http://mediagoblin.server.com/.well-known/host-meta &lt;br /&gt;
&lt;br /&gt;
This is the file other services will GET, based on the host of the email address &#039;&#039;mediagoblin.server.com&#039;&#039; to find out where to get access to more information about the user &#039;&#039;yooser&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The host-meta file can contain a lot of information about the site but the information other federated services are interested in is the Link-based Resource Descriptor Discovery protocol &#039;&#039;lrdd&#039;&#039; (pronounced: lard) information which is provided via a Link with a rel attribute &#039;&#039;lrdd&#039;&#039; and the real information is the associated template (also an attribute of this Link). The template defines a structure of where other federated services can find information about the user account. It is basically just a URL which contains a &#039;&#039;{uri}&#039;&#039; somewhere and this specific &#039;&#039;{uri}&#039;&#039; will be replaced with the user account identifier. This account identifier is the user email preceded by &#039;&#039;acct:&#039;&#039;, i.e. acct:yooser@mediagoblin.server.com&lt;br /&gt;
&lt;br /&gt;
MediaGoblin will then have to decide on how this template should be structured. This could be something like http://mediagoblin.server.com/describe?uri={uri} (which is provided in the discussion of WebFinger) or http://mediagoblin.server.com/main/xrd?uri={uri} (which is the structure on Status.Net). It doesn&#039;t really matter how it is structured, just that it includes the &#039;&#039;{uri}&#039;&#039; and conforms with the overall routing structure of MediaGoblin.&lt;br /&gt;
&lt;br /&gt;
We must also provide a Host element in the host-meta file, in accordance with the host-meta description. For our example this would be &amp;lt;hm:Host&amp;gt;mediagoblin.server.com&amp;lt;/hm:Host&amp;gt; (where the hm namespace is http://host-meta.net/xrd/1.0).&lt;br /&gt;
&lt;br /&gt;
So let&#039;s take a look at an example of what other services might find when they GET the host-meta file for mediagoblin.server.com at http://mediagoblin.server.com/.well-known/host-meta (for this example we&#039;ll use the WebFinger template):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&amp;gt;&lt;br /&gt;
&amp;lt;XRD xmlns=&#039;http://docs.oasis-open.org/ns/xri/xrd-1.0&#039;&lt;br /&gt;
     xmlns:hm=&#039;http://host-meta.net/xrd/1.0&#039;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;hm:Host&amp;gt;mediagoblin.server.com&amp;lt;/hm:Host&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;Link rel=&#039;lrdd&#039;&lt;br /&gt;
          template=&#039;http://mediagoblin.server.com/describe?uri={uri}&#039;&amp;gt;&lt;br /&gt;
        &amp;lt;Title&amp;gt;Resource Descriptor&amp;lt;/Title&amp;gt;&lt;br /&gt;
    &amp;lt;/Link&amp;gt;&lt;br /&gt;
&amp;lt;/XRD&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Django this host-meta file is easily created using Django&#039;s template system and reverse URL lookups. This should be just as easy to do in MediaGoblin&#039;s framework.&lt;br /&gt;
&lt;br /&gt;
Next we have to create the user specific description, i.e. the stuff other federated services will find when they access the template. This is done, as previously discussed by substituting {uri} with the account information (email preceded by acct:) and GETting it. So the other federated services would GET http://mediagoblin.server.com/describe?uri=acct:yooser@mediagoblin.server.com and that would return a whole lot of interesting user specific stuff.&lt;br /&gt;
&lt;br /&gt;
The insteresting stuff is againg presented with XRD and Link elements and could for example be a Link to the profile page (&amp;lt;Link rel=&amp;quot;http://webfinger.net/rel/profile-page&amp;quot; type=&amp;quot;text/html&amp;quot; href=&amp;quot;http://mediagoblin.server.com/u/yooser&amp;quot;/&amp;gt;), the user avatar (&amp;lt;Link rel=&amp;quot;http://webfinger.net/rel/avatar&amp;quot; href=&amp;quot;http://mediagoblin.server.com/u/yooser/avatar&amp;quot; /&amp;gt;). The [http://ostatus.org/2010/10/04/how-ostatus-enable-your-application blog post] says that it should at least include a link to the updates using http://schemas.google.com/g/2010#updates-from which points the the Atom ActivityStream (&amp;lt;Link rel=&amp;quot;http://schemas.google.com/g/2010#updates-from&amp;quot; type=&amp;quot;application/atom+xml&amp;quot; href=&amp;quot;http://mediagoblin.server.com/u/yooser/as.atom&amp;quot; /&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
We must also declare the Subject (the user) in the XRD and we do that using the Subject element which contains the account identifier (email preceded by acct:). We can also Alias the user (using a Alias element) and provide a URL pointing to the user profile page.&lt;br /&gt;
&lt;br /&gt;
So if we look at an example to combine all of this and provide the minimum information needed to enable OStatus (we can always provide more interesting stuff later on or add it when we actually implement WebFinger instead of just describing it on a Wiki page since we add it for subscription and salmon based stuff) the XRD returned when a federated service GETs http://mediagoblin.server.com/describe?uri=acct:yooser@mediagoblin.server.com would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&amp;gt;&lt;br /&gt;
&amp;lt;XRD xmlns=&#039;http://docs.oasis-open.org/ns/xri/xrd-1.0&#039;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;Subject&amp;gt;acct:yooser@mediagoblin.server.com&amp;lt;/Subject&amp;gt;&lt;br /&gt;
    &amp;lt;Alias&amp;gt;http://mediagoblin.server.com/u/yooser&amp;lt;/Alias&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;Link rel=&amp;quot;http://schemas.google.com/g/2010#updates-from&amp;quot;&lt;br /&gt;
          type=&amp;quot;application/atom+xml&amp;quot;&lt;br /&gt;
          href=&amp;quot;http://mediagoblin.server.com/u/yooser/as.atom&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/XRD&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again, this would be easy to do with Django&#039;s template system and reverse URL lookups, and should be just as easy to do with MediaGoblin&#039;s framework. When that is done MediaGoblin will have the WebFinger part of OStatus implemented.&lt;br /&gt;
&lt;br /&gt;
=== Related Links ===&lt;br /&gt;
&lt;br /&gt;
* https://code.google.com/p/webfinger/&lt;br /&gt;
* http://hueniverse.com/2009/08/introducing-webfinger/&lt;br /&gt;
* http://hueniverse.com/2009/09/implementing-webfinger/&lt;br /&gt;
* http://hueniverse.com/2009/03/the-discovery-protocol-stack/&lt;br /&gt;
* http://hueniverse.com/xrd/&lt;br /&gt;
* http://hueniverse.com/2009/11/host-meta-aka-site-meta-and-well-known-uris/&lt;/div&gt;</summary>
		<author><name>Tryggvib</name></author>
	</entry>
	<entry>
		<id>https://wiki.mediagoblin.org/index.php?title=API&amp;diff=378</id>
		<title>API</title>
		<link rel="alternate" type="text/html" href="https://wiki.mediagoblin.org/index.php?title=API&amp;diff=378"/>
		<updated>2011-11-11T12:35:58Z</updated>

		<summary type="html">&lt;p&gt;Tryggvib: Broke up Submission and Metadata into two sections&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes a JSON-based API for MediaGoblin. It is a &#039;&#039;&#039;WORK IN PROGRESS&#039;&#039;&#039; at the moment while it is being drafted before it gets implemented. Currently it only includes a submission API, based on a specific scenario which might not work in general for MediaGoblin but can be used as a springboard for further API improvements and specifications.&lt;br /&gt;
&lt;br /&gt;
= Scenario =&lt;br /&gt;
&lt;br /&gt;
A MediaGoblin server (&#039;&#039;MGS&#039;&#039;) is used for media storage/repository on behalf of a few other servers, called user servers (&#039;&#039;US&#039;&#039;) . A user of one &#039;&#039;US&#039;&#039; submits a multimedia file. The file is sent to the &#039;&#039;MGS&#039;&#039; and categorized on the &#039;&#039;US&#039;&#039; in some server specific way. All future use of the multimedia file on the &#039;&#039;US&#039;&#039; is processed by the &#039;&#039;MGS&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The collection of multimedia files from all of the &#039;&#039;US&#039;&#039;&#039;s is accessible through the &#039;&#039;MGS&#039;&#039; interface and through specific categorizations on each &#039;&#039;US&#039;&#039; via API or direct links to the content on the &#039;&#039;MGS&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Submission ==&lt;br /&gt;
&lt;br /&gt;
Since all files are processed automatically when they are uploaded there is no need for a specific submission api. Media files should therefore just be uploaded using a normal HTTP POST which is made available via the API using some sort of an authentication mechanism. An extra variable, containing a webhook/callback URL, can be sent alongside the file upload. The callback provides a URL to the file in the public store. The &#039;&#039;MGS&#039;&#039; allows the &#039;&#039;US&#039;&#039; to send metadata (for example license information) for the file.&lt;br /&gt;
&lt;br /&gt;
The process is as follows:&lt;br /&gt;
&lt;br /&gt;
# User fills in a form on a &#039;&#039;US&#039;&#039;. The form is in fact based up of two forms&lt;br /&gt;
#* One for categorization on the &#039;&#039;US&#039;&#039;&lt;br /&gt;
#* One is a file form for the &#039;&#039;MGS&#039;&#039;&lt;br /&gt;
# &#039;&#039;US&#039;&#039; saves a pending object with the categorization&lt;br /&gt;
# The &#039;&#039;MGS&#039;&#039; processes the file as usual&lt;br /&gt;
# When the &#039;&#039;MGS&#039;&#039; has finished processing it notifies the &#039;&#039;US&#039;&#039; through a special callback url provided that the processing is finished and the file is available in the public store through a specific url&lt;br /&gt;
# &#039;&#039;US&#039;&#039; moves the object from a pending state to a real object with direct links (or api specific information which might be designed later) to the &#039;&#039;MGS&#039;&#039;&lt;br /&gt;
# &#039;&#039;US&#039;&#039; sends metadata to attach to the file.&lt;br /&gt;
&lt;br /&gt;
=== Callback/finished processing API ===&lt;br /&gt;
&lt;br /&gt;
The callback function of the &#039;&#039;US&#039;&#039; should read and accept MediaGoblin JSON objects according to the following proposed schema when sent to the callback url provided alongside the original upload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
        &amp;quot;name&amp;quot;:&amp;quot;Callback&amp;quot;,&lt;br /&gt;
        &amp;quot;properties&amp;quot;:&lt;br /&gt;
        {&lt;br /&gt;
                &amp;quot;success&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;boolean&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Boolean to indicate whether the processing of the file was successful or not&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;message&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Optional message used when processing was unsuccessful to explain the reason for the failure&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:false&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;location&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;array&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Array of locations for the processed file (or files, e.g. when video file is encoded into the three possible HTML5 video formats&amp;quot;,&lt;br /&gt;
                        &amp;quot;items&amp;quot;:&lt;br /&gt;
                        {&lt;br /&gt;
                                &amp;quot;type&amp;quot;:&amp;quot;object&amp;quot;,&lt;br /&gt;
                                &amp;quot;properties&amp;quot;:&lt;br /&gt;
                                {&lt;br /&gt;
                                        &amp;quot;mimetype&amp;quot;:&lt;br /&gt;
                                        {&lt;br /&gt;
                                                &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                                                &amp;quot;description&amp;quot;:&amp;quot;Mimetype to categorize the file&amp;quot;,&lt;br /&gt;
                                                &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                                        },&lt;br /&gt;
                                        &amp;quot;location&amp;quot;:&lt;br /&gt;
                                        {&lt;br /&gt;
                                                &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                                                &amp;quot;format&amp;quot;:&amp;quot;url&amp;quot;,&lt;br /&gt;
                                                &amp;quot;description&amp;quot;:&amp;quot;URL of the file in the public store&amp;quot;,&lt;br /&gt;
                                                &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                                        },&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
                &amp;quot;mediatype&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Media type of the file categorization, e.g. video, audio, image&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:false&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The MediaGoblin expects status codes 204 (No content) on success (to imitate pubsubhubbub protocol) or normal error codes (4xx or 5xx) to indicate failures. It is possible to further define JSON objects in responses but probably unnecessary. &lt;br /&gt;
&lt;br /&gt;
== Metadata ==&lt;br /&gt;
&lt;br /&gt;
It should be possible to add metadata to a specific file at any time. This could be information such as license information, related files (e.g. derivative work), views on site or something. In this case we only start with a Creative Commons license.&lt;br /&gt;
&lt;br /&gt;
=== Metadata API ===&lt;br /&gt;
&lt;br /&gt;
A proposed json-based api to attach metadata to a file uploaded to a MediaGoblin instance. Other metadata information can be added later. This is just something to start with. It is necessary to check if the calling application is the same as the uploading application (to restrict others from setting metadata to other people&#039;s files).&lt;br /&gt;
&lt;br /&gt;
The following is the JSON Schema for metadata:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
        &amp;quot;name&amp;quot;:&amp;quot;Metadata&amp;quot;,&lt;br /&gt;
        &amp;quot;properties&amp;quot;:&lt;br /&gt;
        {&lt;br /&gt;
                &amp;quot;file&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                        &amp;quot;format&amp;quot;:&amp;quot;url&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;URL to the resource (file) to which metadata should be attached&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;metadata&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;array&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;URL to the resource (file) to which metadata should be attached&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                        &amp;quot;items&amp;quot;:&lt;br /&gt;
                        {&lt;br /&gt;
                                &amp;quot;type&amp;quot;:&amp;quot;object&amp;quot;,&lt;br /&gt;
                                &amp;quot;properties&amp;quot;:&lt;br /&gt;
                                {&lt;br /&gt;
                                        &amp;quot;creativecommons&amp;quot;:&lt;br /&gt;
                                        {&lt;br /&gt;
                                                &amp;quot;type&amp;quot;:&amp;quot;object&amp;quot;,&lt;br /&gt;
                                                &amp;quot;required&amp;quot;:false,&lt;br /&gt;
                                                &amp;quot;properties&amp;quot;:&lt;br /&gt;
                                                {&lt;br /&gt;
                                                        &amp;quot;author&amp;quot;:&lt;br /&gt;
                                                        {&lt;br /&gt;
                                                                &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                                                                &amp;quot;description&amp;quot;:&amp;quot;Original author of the work, used for attribution&amp;quot;,&lt;br /&gt;
                                                                &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                                                        },&lt;br /&gt;
                                                        &amp;quot;license&amp;quot;:&lt;br /&gt;
                                                        {&lt;br /&gt;
                                                                &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                                                                &amp;quot;format&amp;quot;:&amp;quot;url&amp;quot;,&lt;br /&gt;
                                                                &amp;quot;description&amp;quot;:&amp;quot;URL pointing to the Creative Commons license used&amp;quot;,&lt;br /&gt;
                                                                &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                                                        }&lt;br /&gt;
                                                }&lt;br /&gt;
                                        }&lt;br /&gt;
                                }&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of a Claim in JSON would be (it remains to decide how to handle user uploads from sites where users aren&#039;t registerd on MediaGoblin):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
        &amp;quot;file&amp;quot;:&amp;quot;http://media.goblin.com/u/artcollection/water-lilies.jpg&amp;quot;,&lt;br /&gt;
        &amp;quot;metadata&amp;quot;:&lt;br /&gt;
        [&lt;br /&gt;
                &amp;quot;creativecommons&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;author&amp;quot;:&amp;quot;Claude Monet&amp;quot;,&lt;br /&gt;
                        &amp;quot;licence&amp;quot;:&amp;quot;http://creativecommons.org/publicdomain/mark/1.0/&amp;quot;&lt;br /&gt;
                }&lt;br /&gt;
        ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Possible design problems ==&lt;br /&gt;
&lt;br /&gt;
* MediaGoblin is user based but who is the user when files are sent in by users on a specific site? Use OAuth/OpenID? Perhaps tie closely with OStatus federation. Probably best to follow Twitter API where applications must be registered and get an API key for uploading.&lt;br /&gt;
* Mediatype for callback needs a better definition in the API (what can be sent, e.g. .)&lt;/div&gt;</summary>
		<author><name>Tryggvib</name></author>
	</entry>
	<entry>
		<id>https://wiki.mediagoblin.org/index.php?title=API&amp;diff=377</id>
		<title>API</title>
		<link rel="alternate" type="text/html" href="https://wiki.mediagoblin.org/index.php?title=API&amp;diff=377"/>
		<updated>2011-11-11T12:19:53Z</updated>

		<summary type="html">&lt;p&gt;Tryggvib: Changes to API proposal according to IRC discussion on #mediagoblin (I hope I didn&amp;#039;t screw things up)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes a JSON-based API for MediaGoblin. It is a &#039;&#039;&#039;WORK IN PROGRESS&#039;&#039;&#039; at the moment while it is being drafted before it gets implemented. Currently it only includes a submission API, based on a specific scenario which might not work in general for MediaGoblin but can be used as a springboard for further API improvements and specifications.&lt;br /&gt;
&lt;br /&gt;
= Scenario =&lt;br /&gt;
&lt;br /&gt;
A MediaGoblin server (&#039;&#039;MGS&#039;&#039;) is used for media storage/repository on behalf of a few other servers, called user servers (&#039;&#039;US&#039;&#039;) . A user of one &#039;&#039;US&#039;&#039; submits a multimedia file. The file is sent to the &#039;&#039;MGS&#039;&#039; and categorized on the &#039;&#039;US&#039;&#039; in some server specific way. All future use of the multimedia file on the &#039;&#039;US&#039;&#039; is processed by the &#039;&#039;MGS&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The collection of multimedia files from all of the &#039;&#039;US&#039;&#039;&#039;s is accessible through the &#039;&#039;MGS&#039;&#039; interface and through specific categorizations on each &#039;&#039;US&#039;&#039; via API or direct links to the content on the &#039;&#039;MGS&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Submission ==&lt;br /&gt;
&lt;br /&gt;
Since all files are processed automatically when they are uploaded there is no need for a specific submission api. Media files should therefore just be uploaded using a normal HTTP POST which is made available via the API using some sort of an authentication mechanism. An extra variable, containing a webhook/callback URL, can be sent alongside the file upload. The callback provides a URL to the file in the public store. The &#039;&#039;MGS&#039;&#039; allows the &#039;&#039;US&#039;&#039; to send metadata (for example license information) for the file.&lt;br /&gt;
&lt;br /&gt;
The process is as follows:&lt;br /&gt;
&lt;br /&gt;
# User fills in a form on a &#039;&#039;US&#039;&#039;. The form is in fact based up of two forms&lt;br /&gt;
#* One for categorization on the &#039;&#039;US&#039;&#039;&lt;br /&gt;
#* One is a file form for the &#039;&#039;MGS&#039;&#039;&lt;br /&gt;
# &#039;&#039;US&#039;&#039; saves a pending object with the categorization&lt;br /&gt;
# The &#039;&#039;MGS&#039;&#039; processes the file as usual&lt;br /&gt;
# When the &#039;&#039;MGS&#039;&#039; has finished processing it notifies the &#039;&#039;US&#039;&#039; through a special callback url provided that the processing is finished and the file is available in the public store through a specific url&lt;br /&gt;
# &#039;&#039;US&#039;&#039; moves the object from a pending state to a real object with direct links (or api specific information which might be designed later) to the &#039;&#039;MGS&#039;&#039;&lt;br /&gt;
# &#039;&#039;US&#039;&#039; sends metadata to attach to the file.&lt;br /&gt;
&lt;br /&gt;
=== Callback/finished processing API ===&lt;br /&gt;
&lt;br /&gt;
The callback function of the &#039;&#039;US&#039;&#039; should read and accept MediaGoblin JSON objects according to the following proposed schema when sent to the callback url provided alongside the original upload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
        &amp;quot;name&amp;quot;:&amp;quot;Callback&amp;quot;,&lt;br /&gt;
        &amp;quot;properties&amp;quot;:&lt;br /&gt;
        {&lt;br /&gt;
                &amp;quot;success&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;boolean&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Boolean to indicate whether the processing of the file was successful or not&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;message&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Optional message used when processing was unsuccessful to explain the reason for the failure&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:false&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;location&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;array&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Array of locations for the processed file (or files, e.g. when video file is encoded into the three possible HTML5 video formats&amp;quot;,&lt;br /&gt;
                        &amp;quot;items&amp;quot;:&lt;br /&gt;
                        {&lt;br /&gt;
                                &amp;quot;type&amp;quot;:&amp;quot;object&amp;quot;,&lt;br /&gt;
                                &amp;quot;properties&amp;quot;:&lt;br /&gt;
                                {&lt;br /&gt;
                                        &amp;quot;mimetype&amp;quot;:&lt;br /&gt;
                                        {&lt;br /&gt;
                                                &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                                                &amp;quot;description&amp;quot;:&amp;quot;Mimetype to categorize the file&amp;quot;,&lt;br /&gt;
                                                &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                                        },&lt;br /&gt;
                                        &amp;quot;location&amp;quot;:&lt;br /&gt;
                                        {&lt;br /&gt;
                                                &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                                                &amp;quot;format&amp;quot;:&amp;quot;url&amp;quot;,&lt;br /&gt;
                                                &amp;quot;description&amp;quot;:&amp;quot;URL of the file in the public store&amp;quot;,&lt;br /&gt;
                                                &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                                        },&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
                &amp;quot;mediatype&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Media type of the file categorization, e.g. video, audio, image&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:false&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The MediaGoblin expects status codes 204 (No content) on success (to imitate pubsubhubbub protocol) or normal error codes (4xx or 5xx) to indicate failures. It is possible to further define JSON objects in responses but probably unnecessary. &lt;br /&gt;
&lt;br /&gt;
=== Metadata API ===&lt;br /&gt;
&lt;br /&gt;
A proposed json-based api to attach metadata to a file uploaded to a MediaGoblin instance. Other metadata information can be added later. This is just something to start with. It is necessary to check if the calling application is the same as the uploading application (to restrict others from setting metadata to other people&#039;s files).&lt;br /&gt;
&lt;br /&gt;
The following is the JSON Schema for metadata:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
        &amp;quot;name&amp;quot;:&amp;quot;Metadata&amp;quot;,&lt;br /&gt;
        &amp;quot;properties&amp;quot;:&lt;br /&gt;
        {&lt;br /&gt;
                &amp;quot;file&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                        &amp;quot;format&amp;quot;:&amp;quot;url&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;URL to the resource (file) to which metadata should be attached&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;metadata&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;array&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;URL to the resource (file) to which metadata should be attached&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                        &amp;quot;items&amp;quot;:&lt;br /&gt;
                        {&lt;br /&gt;
                                &amp;quot;type&amp;quot;:&amp;quot;object&amp;quot;,&lt;br /&gt;
                                &amp;quot;properties&amp;quot;:&lt;br /&gt;
                                {&lt;br /&gt;
                                        &amp;quot;creativecommons&amp;quot;:&lt;br /&gt;
                                        {&lt;br /&gt;
                                                &amp;quot;type&amp;quot;:&amp;quot;object&amp;quot;,&lt;br /&gt;
                                                &amp;quot;required&amp;quot;:false,&lt;br /&gt;
                                                &amp;quot;properties&amp;quot;:&lt;br /&gt;
                                                {&lt;br /&gt;
                                                        &amp;quot;author&amp;quot;:&lt;br /&gt;
                                                        {&lt;br /&gt;
                                                                &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                                                                &amp;quot;description&amp;quot;:&amp;quot;Original author of the work, used for attribution&amp;quot;,&lt;br /&gt;
                                                                &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                                                        },&lt;br /&gt;
                                                        &amp;quot;license&amp;quot;:&lt;br /&gt;
                                                        {&lt;br /&gt;
                                                                &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                                                                &amp;quot;format&amp;quot;:&amp;quot;url&amp;quot;,&lt;br /&gt;
                                                                &amp;quot;description&amp;quot;:&amp;quot;URL pointing to the Creative Commons license used&amp;quot;,&lt;br /&gt;
                                                                &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                                                        }&lt;br /&gt;
                                                }&lt;br /&gt;
                                        }&lt;br /&gt;
                                }&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of a Claim in JSON would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
        &amp;quot;file&amp;quot;:&amp;quot;http://media.goblin.com/b5d9f282-08ce-11e1-93a3-b32377194cc9.png&amp;quot;,&lt;br /&gt;
        &amp;quot;metadata&amp;quot;:&lt;br /&gt;
        [&lt;br /&gt;
                &amp;quot;creativecommons&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;author&amp;quot;:&amp;quot;Claude Monet&amp;quot;,&lt;br /&gt;
                        &amp;quot;licence&amp;quot;:&amp;quot;http://creativecommons.org/publicdomain/mark/1.0/&amp;quot;&lt;br /&gt;
                }&lt;br /&gt;
        ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Possible design problems ===&lt;br /&gt;
&lt;br /&gt;
* MediaGoblin is user based but who is the user when files are sent in by users on a specific site? Use OAuth/OpenID? Perhaps tie closely with OStatus federation. Probably best to follow Twitter API where applications must be registered and get an API key for uploading.&lt;br /&gt;
* Mediatype needs a better definition in the API (what can be sent, e.g. .)&lt;/div&gt;</summary>
		<author><name>Tryggvib</name></author>
	</entry>
	<entry>
		<id>https://wiki.mediagoblin.org/index.php?title=API&amp;diff=368</id>
		<title>API</title>
		<link rel="alternate" type="text/html" href="https://wiki.mediagoblin.org/index.php?title=API&amp;diff=368"/>
		<updated>2011-11-06T23:52:42Z</updated>

		<summary type="html">&lt;p&gt;Tryggvib: Created a page with a proposed start for the MediaGoblin API&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes a JSON-based API for MediaGoblin. It is a &#039;&#039;&#039;WORK IN PROGRESS&#039;&#039;&#039; at the moment while it is being drafted before it gets implemented. Currently it only includes a submission API, based on a specific scenario which might not work in general for MediaGoblin but can be used as a springboard for further API improvements and specifications.&lt;br /&gt;
&lt;br /&gt;
= Scenario =&lt;br /&gt;
&lt;br /&gt;
A MediaGoblin server (&#039;&#039;MGS&#039;&#039;) is used for media storage/repository on behalf of a few other servers, called user servers (&#039;&#039;US&#039;&#039;) . A user of one &#039;&#039;US&#039;&#039; submits a multimedia file. The file is sent to the &#039;&#039;MGS&#039;&#039; and categorized on the &#039;&#039;US&#039;&#039; in some server specific way. All future use of the multimedia file on the &#039;&#039;US&#039;&#039; is processed by the &#039;&#039;MGS&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The collection of multimedia files from all of the &#039;&#039;US&#039;&#039;&#039;s is accessible through the &#039;&#039;MGS&#039;&#039; interface and through specific categorizations on each &#039;&#039;US&#039;&#039; via API or direct links to the content on the &#039;&#039;MGS&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Submission ==&lt;br /&gt;
&lt;br /&gt;
For submission files are sent directly to the &#039;&#039;MGS&#039;&#039; for processing. Each &#039;&#039;US&#039;&#039; has to claim the uploaded multimedia file to start processing. The process is as follows:&lt;br /&gt;
&lt;br /&gt;
# User fills in a form on a &#039;&#039;US&#039;&#039;. The form is in fact based up of two forms&lt;br /&gt;
#* One for categorization on the &#039;&#039;US&#039;&#039;&lt;br /&gt;
#* One is a file form for the &#039;&#039;MGS&#039;&#039;&lt;br /&gt;
# File is sent to the &#039;&#039;MGS&#039;&#039; with a unique name&lt;br /&gt;
#* The name distinction should be designed to ensure uniqueness (perhaps uuid?)&lt;br /&gt;
# &#039;&#039;US&#039;&#039; saves a pending object with the categorization&lt;br /&gt;
# &#039;&#039;US&#039;&#039; claims the file through the unique name via an API which start the processing of the file&lt;br /&gt;
# The &#039;&#039;MGS&#039;&#039; processes the file as usual&lt;br /&gt;
# When the &#039;&#039;MGS&#039;&#039; has finished processing it notifies the &#039;&#039;US&#039;&#039; through a special callback url provided that the processing is finished and the file is available in the public store through a specific url&lt;br /&gt;
# &#039;&#039;US&#039;&#039; moves the object from a pending state to a real object with direct links (or api specific information which might be designed later) to the &#039;&#039;MGS&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== File claim/start processing API ===&lt;br /&gt;
&lt;br /&gt;
A proposed json-based api to claim a file uploaded to a MediaGoblin instance. When a file is claimed, the necessary variables are the unique filename, the callback url and the uploader (uses OStatus WebFinger id). The request can of course also contains other metadata and in this scenario we add Creative Commons metadata like original author and license.&lt;br /&gt;
&lt;br /&gt;
The following is the JSON Schema for the file claim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
        &amp;quot;name&amp;quot;:&amp;quot;Claim&amp;quot;,&lt;br /&gt;
        &amp;quot;properties&amp;quot;:&lt;br /&gt;
        {&lt;br /&gt;
                &amp;quot;filename&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Unique, claimable filename of an uploaded file on the MediaGoblin server&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;callback&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                        &amp;quot;format&amp;quot;:&amp;quot;url&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;URL to call when processing is completed/failed for notification&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;uploader&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                        &amp;quot;format&amp;quot;:&amp;quot;email&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Webfinger email address of the uploader for identification&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;creativecommons&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;object&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:false,&lt;br /&gt;
                        &amp;quot;properties&amp;quot;:&lt;br /&gt;
                        {&lt;br /&gt;
                                &amp;quot;author&amp;quot;:&lt;br /&gt;
                                {&lt;br /&gt;
                                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                                        &amp;quot;description&amp;quot;:&amp;quot;Original author of the work, used for attribution&amp;quot;,&lt;br /&gt;
                                        &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                                },&lt;br /&gt;
                                &amp;quot;license&amp;quot;:&lt;br /&gt;
                                {&lt;br /&gt;
                                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                                        &amp;quot;format&amp;quot;:&amp;quot;url&amp;quot;,&lt;br /&gt;
                                        &amp;quot;description&amp;quot;:&amp;quot;URL pointing to the Creative Commons license used&amp;quot;,&lt;br /&gt;
                                        &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                                }&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of a Claim in JSON would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
        &amp;quot;filename&amp;quot;:&amp;quot;b5d9f282-08ce-11e1-93a3-b32377194cc9.png&amp;quot;,&lt;br /&gt;
        &amp;quot;callback&amp;quot;:&amp;quot;http://example.com/pending/b5d9f282-08ce-11e1-93a3-b32377194cc9/&amp;quot;,&lt;br /&gt;
        &amp;quot;uploader&amp;quot;:&amp;quot;user@example.com&amp;quot;,&lt;br /&gt;
        &amp;quot;creativecommons&amp;quot;:&lt;br /&gt;
        {&lt;br /&gt;
                &amp;quot;author&amp;quot;:&amp;quot;Claude Monet&amp;quot;,&lt;br /&gt;
                &amp;quot;licence&amp;quot;:&amp;quot;http://creativecommons.org/publicdomain/mark/1.0/&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Callback/finished processing API ===&lt;br /&gt;
&lt;br /&gt;
The callback function of the &#039;&#039;US&#039;&#039; should read and accept MediaGoblin JSON objects according to the following proposed schema when sent to the callback url provided in the original claim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
        &amp;quot;name&amp;quot;:&amp;quot;Callback&amp;quot;,&lt;br /&gt;
        &amp;quot;properties&amp;quot;:&lt;br /&gt;
        {&lt;br /&gt;
                &amp;quot;success&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;boolean&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Boolean to indicate whether the processing of the file was successful or not&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;message&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Optional message used when processing was unsuccessful to explain the reason for the failure&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:false&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;location&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;array&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Array of locations for the processed file (or files, e.g. when video file is encoded into the three possible HTML5 video formats&amp;quot;,&lt;br /&gt;
                        &amp;quot;items&amp;quot;:&lt;br /&gt;
                        {&lt;br /&gt;
                                &amp;quot;type&amp;quot;:&amp;quot;object&amp;quot;,&lt;br /&gt;
                                &amp;quot;properties&amp;quot;:&lt;br /&gt;
                                {&lt;br /&gt;
                                        &amp;quot;mediatype&amp;quot;:&lt;br /&gt;
                                        {&lt;br /&gt;
                                                &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                                                &amp;quot;description&amp;quot;:&amp;quot;Optional string to categorize the file, e.g. ogv, webm&amp;quot;,&lt;br /&gt;
                                                &amp;quot;required&amp;quot;:false,&lt;br /&gt;
                                        },&lt;br /&gt;
                                        &amp;quot;location&amp;quot;:&lt;br /&gt;
                                        {&lt;br /&gt;
                                                &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                                                &amp;quot;format&amp;quot;:&amp;quot;url&amp;quot;,&lt;br /&gt;
                                                &amp;quot;description&amp;quot;:&amp;quot;URL of the file in the public store&amp;quot;,&lt;br /&gt;
                                                &amp;quot;required&amp;quot;:true,&lt;br /&gt;
                                        },&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
                &amp;quot;mimetype&amp;quot;:&lt;br /&gt;
                {&lt;br /&gt;
                        &amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;,&lt;br /&gt;
                        &amp;quot;description&amp;quot;:&amp;quot;Mimetype of the file to allow receiver to categorize pending object&amp;quot;,&lt;br /&gt;
                        &amp;quot;required&amp;quot;:true&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Possible design problems ===&lt;br /&gt;
&lt;br /&gt;
* Requires a separate upload (or possibly a rewrite of the current upload) to enable &#039;&#039;file claims&#039;&#039;&lt;br /&gt;
* A secure and unique filename to be claimed is needed&lt;br /&gt;
* MediaGoblin is user based but who is the user when files are sent in by users on a specific site? Use OAuth/OpenID? Perhaps tie closely with OStatus federation.&lt;br /&gt;
* Need a service to remove old unclaimed files (and what would be the time window?)&lt;br /&gt;
* Mediatype needs a better definition in the API (what can be sent, e.g. webm or WebM etc.)&lt;/div&gt;</summary>
		<author><name>Tryggvib</name></author>
	</entry>
</feed>