Difference between revisions of "Team:Freiburg/Wikimigration"

(Created page with "{{Freiburg/CSS}} {{Freiburg/Menubar}} {{Freiburg/wiki_content_start}} <html> <h1 class="sectionedit1">How to migrate to the iGEM-Wiki: the Freiburg way</h1> <div class="le...")
 
 
(9 intermediate revisions by 4 users not shown)
Line 2: Line 2:
 
{{Freiburg/Menubar}}
 
{{Freiburg/Menubar}}
  
{{Freiburg/wiki_content_start}}
+
{{Team:Freiburg/wiki_content_start_bubble}}
 
<html>
 
<html>
 +
<style>
  
+
code{
 +
    font-size:80%;
 +
}
 +
 
 +
/*========= BEGIN: style for navigation bar ==========*/
 +
#notebook {
 +
    background: url(https://static.igem.org/mediawiki/2015/c/cd/Freiburg_icon_notebook_active_yellow.png) no-repeat;
 +
}
 +
 
 +
#notebook a {
 +
    color: #ecdc18;
 +
}
 +
 
 +
#runningchip {
 +
    left: 85.5%;
 +
}
 +
/*========= END: style for navigation bar ==========*/
 +
</style>
 +
 
 +
<script type="text/javascript">
 +
//===================BEGIN:Amazing Bubble Sidebar==========================
 +
 
 +
$(document).ready(function(){
 +
  // CHANGE THE FOLLOWING ATTRIBUTES //
 +
  var href_text1='https://2015.igem.org/Team:Freiburg/Notebook',
 +
  // Text2 needs no href as it is the actual page //
 +
  img_url='https://static.igem.org/mediawiki/2015/9/99/Freibur_icon_notebook_white_03.png',
 +
  href_text3='https://2015.igem.org/Team:Freiburg/Glossary',
 +
  // Text1 needs no text as it is a pic //
 +
  text2='Wiki-Tricks';
 +
  // Text3 needs no text as its always 'next' //
 +
  // HOLD ON CHANGING THINGS --JABBERWOCK  //
 +
 
 +
  $('#bubble1').attr('href',href_text1);
 +
  $('#bubble1_img').attr('src', img_url);
 +
  $('#bubble3').attr('href',href_text3);
 +
 
 +
  $('#bubble2').text(text2);
 +
});
 +
 
 +
//===================END:Amazing Bubble Sidebar==========================
 +
</script>
  
<h1 class="sectionedit1">How to migrate to the iGEM-Wiki: the Freiburg way</h1>
+
<div class="content_box">
<div class="level1">
+
<h1>How to Migrate to the iGEM-Wiki: The Freiburg Way</h1>
 
<p>
 
<p>
At the end of an iGEM summer writing the final wiki in time for wiki freeze is a challenge every iGEM team experiences. But apart from designing the wiki itself, using <acronym title="Cascading Style Sheets">CSS</acronym> and Javascript, a main problem is the content. A final iGEM wiki should on the one hand be good to read and inspire people for science, on the other hand all the information needed to repeat the experiments has to be provided for good scientific practice. And especially for this last aspect we would like to show how we worked on our wiki and what may be adaptable for future teams.
+
At the end of an iGEM summer writing the final wiki in time for wiki freeze is a challenge every iGEM team experiences. But apart from designing the wiki itself, using CSS and Javascript, a main problem is the content. A final iGEM wiki should on the one hand be good to read and inspire people for science, on the other hand all the information needed to repeat the experiments has to be provided for good scientific practice. And especially for this last aspect we would like to show how we worked on our wiki and what may be adaptable for future teams.
 
</p>
 
</p>
</div>
+
 
 
<!-- EDIT1 SECTION "How to migrate to the iGEM-Wiki: the Freiburg way" [1-621] -->
 
<!-- EDIT1 SECTION "How to migrate to the iGEM-Wiki: the Freiburg way" [1-621] -->
<h2 class="sectionedit2">The internal Wiki</h2>
+
<h2>The Internal Wiki</h2>
<div class="level2">
+
 
<p>
 
<p>
To start early and to document every step we did, we worked with a so called internal wiki that was based on dokuwiki and hosted on the university's web server. A special advantage of this wiki-system was an introductory course provided by the university and the relative simple formatting syntax that allowed direct work without long learning periods. Additionally the wiki is used to organize our team, to protocol meetings and to provide information such as scientific papers and protocols as well as cooking recipes that were tested during these meetings. But a major drawback from using dokuwiki was that the syntax is not at all compatible with the mediawiki syntax that is used on the external official iGEM wiki. To not rewrite all articels we thought for a solution to convert content between these wikis in a fast and simple way.
+
To start early and to document every step we did, we worked with a so called internal wiki that was based on dokuwiki and hosted on the university's web server. A special advantage of this wiki-system was an introductory course provided by the university and the relatively simple formatting syntax that allowed direct work without long learning periods. Additionally the wiki is used to organize our team, to protocol meetings and to provide information such as scientific papers and protocols as well as cooking recipes that we tested during these meetings. But a major drawback from using dokuwiki was that the syntax is not at all compatible with the mediawiki syntax that is used on the external official iGEM wiki. To not rewrite all articels we thought for a solution to convert content between these wikis in a fast and simple way.
 
</p>
 
</p>
</div>
+
 
 
<!-- EDIT2 SECTION "The internal Wiki" [622-1492] -->
 
<!-- EDIT2 SECTION "The internal Wiki" [622-1492] -->
<h2 class="sectionedit3">Migration</h2>
+
<h2>Migration</h2>
<div class="level2">
+
 
<div class="image_box right">
 
<div class="image_box right">
<div class="thumb2 tright" style="width:310px"><div class="thumbinner"><a class="media" href="https://static.igem.org/mediawiki/2015/0/05/Freiburg_files-wikitranslate_form.png" title="files:wikitranslate_form.png"><img alt="" class="mediabox2" src="https://static.igem.org/mediawiki/2015/0/05/Freiburg_files-wikitranslate_form.png" width="300"/></a><div class="thumbcaption"><div class="magnify"><a class="internal" href="https://static.igem.org/mediawiki/2015/0/05/Freiburg_files-wikitranslate_form.png" title="vergrößern"><img alt="" height="11" src="/igem2015/lib/plugins/imagebox/magnify-clip.png" width="15"/></a></div>Form providing input for the wikitranslate script</div></div></div>
+
<div class="thumb2 tright" style="width:310px">
 +
<div class="thumbinner">
 +
<a class="media" href="https://static.igem.org/mediawiki/2015/0/05/Freiburg_files-wikitranslate_form.png" title="files:wikitranslate_form.png">
 +
<img alt="" class="mediabox2" src="https://static.igem.org/mediawiki/2015/0/05/Freiburg_files-wikitranslate_form.png" width="300"/>
 +
</a>
 +
<div class="thumbcaption">
 +
<div class="magnify">
 +
<a class="internal" href="https://static.igem.org/mediawiki/2015/0/05/Freiburg_files-wikitranslate_form.png" title="vergrößern">
 +
<img alt="" height="11" src="/igem2015/lib/plugins/imagebox/magnify-clip.png" width="15"/>
 +
</a>
 +
</div>Form providing input for the wikitranslate script
 +
</div>
 +
</div>
 +
</div>
 
</div>
 
</div>
 
<p>
 
<p>
Even though the dokuwiki provides a feature to export the page's body content (by appending <code>&amp;do=export_xhtmlbody</code> to the <acronym title="Uniform Resource Locator">URL</acronym> and getting the source code of this via <code>STRG+U</code> in Firefox) all the image links refer to the internal server and are, therefore, broken. The first step in migrating our content, thus was a script to download all the images of a specified internal wiki page and prefix the file names with <code>Freiburg_</code> to avoid name conflicts with other teams. The program also outputs a file with all the file names separated by commas that is later used to upload the files.
+
Even though the dokuwiki provides a feature to export the page's body content (by appending &amp;do=export_xhtmlbody to the <acronym title="Uniform Resource Locator">URL</acronym> and getting the source code of this via STRG+U in Firefox) all the image links refer to the internal server and are, therefore, broken. The first step in migrating our content, thus was a script to download all the images of a specified internal wiki page and prefix the file names with Freiburg_ to avoid name conflicts with other teams. The program also outputs a file with all the file names separated by commas that is later used to upload the files.
To transfer the downloaded and renamed files onto the iGEM server the selenium browser automation tool (<a class="urlextern" href="http://www.seleniumhq.org/" rel="nofollow" target="_Blank" title="http://www.seleniumhq.org/">http://www.seleniumhq.org/</a>) in combination with the sideflow-plugin (<a class="urlextern" href="https://github.com/73rhodes/sideflow" rel="nofollow" target="_Blank" title="https://github.com/73rhodes/sideflow">https://github.com/73rhodes/sideflow</a>) was used. This plugin allows for the creation of loops in selenium routines as needed to upload a list of files. The steps in the selenium routine are basically the coded equivalent to clicking on the upload-button, selecting a file, clicking the <code>ignore any warnings</code> button and submit the form.
+
To transfer the downloaded and renamed files onto the iGEM server the selenium browser automation tool (<a class="urlextern" href="http://www.seleniumhq.org/" rel="nofollow" target="_Blank" title="http://www.seleniumhq.org/">http://www.seleniumhq.org/</a>) in combination with the sideflow-plugin (<a class="urlextern" href="https://github.com/73rhodes/sideflow" rel="nofollow" target="_Blank" title="https://github.com/73rhodes/sideflow">https://github.com/73rhodes/sideflow</a>) was used. This plugin allows for the creation of loops in selenium routines as needed to upload a list of files. The steps in the selenium routine are basically the coded equivalent to clicking on the upload-button, selecting a file, clicking the ignore any warnings button and submit the form.
Once the files are on the server, it is necessary to get their location on this server to use it as image source in the html-text on the sites. As the iGEM Server assigns a variable path to every file (as <code>/e/e4/filename.png</code>) this path has to be probed for every single image to be used on the site.
+
Once the files are on the server, it is necessary to get their location on this server to use it as image source in the html-text on the sites. As the iGEM Server assigns a variable path to every file (as /e/e4/filename.png) this path has to be probed for every single image to be used on the site.
 
This routine is implemented in the wikitranslate script together with a routine for replacing the linked headers by unlinked ones and one for adding preceding and following text, such that, for example custom styling for a specific page can be done directly in the protocol. The script is used on a web server basis (as cgi - script) and thus can be used by every team member with no needs for programming skills. It then returns an html-file that contains the source code to paste in the manually created new external wiki page.
 
This routine is implemented in the wikitranslate script together with a routine for replacing the linked headers by unlinked ones and one for adding preceding and following text, such that, for example custom styling for a specific page can be done directly in the protocol. The script is used on a web server basis (as cgi - script) and thus can be used by every team member with no needs for programming skills. It then returns an html-file that contains the source code to paste in the manually created new external wiki page.
 
</p>
 
</p>
</div>
+
 
 
<!-- EDIT3 SECTION "Migration" [1493-3548] -->
 
<!-- EDIT3 SECTION "Migration" [1493-3548] -->
<h2 class="sectionedit4">Refining the external Wiki</h2>
+
<h2 class="sectionedit4">Refining the External Wiki</h2>
<div class="level2">
+
 
<p>
 
<p>
 
Despite lowering a lot the workload needed for transferring our content to the external wiki, there still is need to adapt the design by hand. A major aspect here is a consistent design of the uploaded pages with the ones created especially for the external wiki, as the landing page or the project overview pages.
 
Despite lowering a lot the workload needed for transferring our content to the external wiki, there still is need to adapt the design by hand. A major aspect here is a consistent design of the uploaded pages with the ones created especially for the external wiki, as the landing page or the project overview pages.
 
All in all, using an automated uploading and replacing procedure to transfer our content from the internal to the external wiki allowed us to spend more time on the remaining pages, like our poster and the presentation. And we hope that our experiences might also be useful for other teams writing their content in advance.
 
All in all, using an automated uploading and replacing procedure to transfer our content from the internal to the external wiki allowed us to spend more time on the remaining pages, like our poster and the presentation. And we hope that our experiences might also be useful for other teams writing their content in advance.
 
</p>
 
</p>
</div>
+
 
 
<!-- EDIT4 SECTION "Refining the external Wiki" [3549-4226] -->
 
<!-- EDIT4 SECTION "Refining the external Wiki" [3549-4226] -->
 
<h2 class="sectionedit5">Script-Code</h2>
 
<h2 class="sectionedit5">Script-Code</h2>
<div class="level2">
+
 
<div class="tags"><span>
+
 
 +
 
 +
<div class="accordion">
 +
  <div class="accordion-section">
 +
    <a class="accordion-section-title" href="#accordion-1">dwfileload.py:</a>
 +
    <div id="accordion-1" class="accordion-section-content" style="display:none; padding:15px;">
 +
    <div class="table sectionedit6">     
 +
   
 +
#!/usr/bin/env python<br/><br/> from bs4 import BeautifulSoup # parse raw html and extract elements<br/> import requests<br/> from requests.auth import HTTPBasicAuth<br/> import cgi<br/> import urllib3<br/><br/> ##################<br/> # DEFINITIONS<br/> ##################<br/><br/> def getdwsource(dwsite):<br/>     # get the subsite of the internal wiki specified as site<br/>     # use the dummy usre to provide access to the wiki<br/>     dokuwiki=requests.get('https://wiki.uni-freiburg.de/igem2015/doku.php?id=%s&amp;do=export_xhtmlbody'%dwsite, auth=HTTPBasicAuth('dummy', 'igem2015'))<br/>     # extract the html of the requests-object by using beautifulsoup<br/>     soup=BeautifulSoup(dokuwiki.text,  'html.parser')<br/>     # print('https://wiki.uni-freiburg.de/igem2015/doku.php?id=%s&amp;do=export_xhtmlbody'%site)<br/>     return soup<br/>     <br/> def getdwpicnames(source):<br/>     ########<br/>     # returns a dict of the the names of all images in the source code as keys with the corresponding links to the image and the info-page<br/>     ########<br/>     picnamesdic={}<br/>     for img in source.find_all('img'):<br/>         # extract the name of all pictures from the src-string<br/>         try:<br/>             # get the name of the picnamesdic<br/>             dwname=img.get('src').split('media=')[1]<br/>             # use the name as key for a dict to store the links for src and href<br/>             picnamesdic[dwname]=[img.get('src')]<br/>             picnamesdic[dwname].append(img.parent.get('href'))<br/>             print('+ \t %s '%img.get('src').split('media=')[1])<br/>             # print('dwlink=%s'%picnamesdic[dwname])<br/>         except:<br/>             print('- \t\t %s '%img.get('src').split('/')[-1])<br/>     return picnamesdic<br/><br/> def unescape(s):<br/>     s = s.replace(&quot;&amp;lt;&quot;, &quot;&lt;&quot;)<br/>     s = s.replace(&quot;&amp;gt;&quot;, &quot;&gt;&quot;)<br/>     s = s.replace(&quot;%3A&quot;, &quot;:&quot;)<br/>     # this has to be last:<br/>     s = s.replace(&quot;&amp;amp;&quot;, &quot;&amp;&quot;)<br/>     return s<br/><br/> def getpicurl(picname):<br/>     <br/>     # input: The name of a file uploaded on the iGEM 2015 Wiki-Server #<br/>     # IMPOARTNT: The picture has to be uploaded before running the script! #<br/>     # picname=input('please paste the name of an uploaded iGEM-wiki file:\n')<br/>     <br/>     # correct picname for changes the iGEM-Server needs<br/>     picname=picname.replace(':','-' )<br/>     <br/>     # define fix url for Wiki-Sever #<br/>     url='https://2015.igem.org/File:Freiburg_%s'%picname<br/>     print('the url I looked for was:\n%s' %url)<br/>     <br/>     # get raw_html from url as specified here: http://stackoverflow.com/questions/17257912/how-to-print-raw-html-string-using-urllib3 #<br/>     <br/>     http_pool = urllib3.connection_from_url(url)<br/>     r = http_pool.urlopen('GET',url)<br/>     raw_html=r.data.decode('utf-8')<br/>     <br/>     # initialise bs-object '<br/>     soup = BeautifulSoup(raw_html, 'html.parser')<br/>     <br/>     # find the href-link in an a-object in a div with id=file #<br/>     try:<br/>         serverlink='https://2015.igem.org'+soup.find(id='file').find('a').get('href')<br/>         # return the link #<br/>         return '%(x)s, %(y)s' % {'x': picname, 'y' : serverlink}<br/>     except:<br/>         return None<br/><br/><br/> ###################<br/> # BEGIN PROGRAMME<br/> ###################<br/><br/> # ask for internal wiki site to read<br/> dwsite=input('dwsite (in please in quotations):\t')<br/> # get sourcecode<br/> dwsource=getdwsource(dwsite)<br/> # get all picture names within a href<br/> picnamesdic=getdwpicnames(dwsource)<br/> # initialize list of urls to download<br/> urldic = {}<br/> # fill the list<br/> for key in picnamesdic:<br/>     if getpicurl(key) == None:<br/>         urldic[key]='/igem2015/lib/exe/fetch.php?media='+key<br/><br/> # download the images in the current directory (replace non usable syntax and append Freiburg_)<br/> for url in urldic:<br/>     r=requests.get('http://wiki.uni-freiburg.de'+urldic[url], auth=HTTPBasicAuth('dummy', 'igem2015'),  stream=True)<br/>     if r.status_code == 200:<br/>         f = open('Freiburg_'+url.replace(':','-'), 'wb')<br/>         f.write(r.content)<br/>         f.close()<br/><br/> f = open('files.txt', 'a')<br/> for key in urldic.keys():<br/> f.write('&quot;{}&quot;'.format(key.replace(':','-')))<br/> f.write(', ')<br/> f.close()<br/>
 +
 
 +
 +
  </div>
 +
    </div><!-- end accordion-section-content -->
 +
  </div><!-- end accordion-section -->
 +
</div> <!-- end accordion -->
 +
 
 +
 
 +
<p>
 +
</p>
 +
 
 +
 
 +
<div class="accordion">
 +
  <div class="accordion-section">
 +
    <a class="accordion-section-title" href="#accordion-2">Presets for Selenium IDE</a>
 +
    <div id="accordion-2" class="accordion-section-content" style="display:none; padding:15px;">
 +
      <div class="table sectionedit6">
 +
 
 +
      <table summary="fileupload" id="fileupload" >
 +
<tr>
 +
<th>command</th>
 +
<th>target</th>
 +
<th>value</th>
 +
</tr>
 +
<tr>
 +
<td>storeEval</td>
 +
<td>new Array(YOURARRAY);</td>
 +
<td>myarray</td>
 +
</tr>
 +
<tr>
 +
<td>getEval</td>
 +
<td>index=0;</td>
 +
<td></td>
 +
</tr>
 +
<tr>
 +
<td>while</td>
 +
<td>index &lt; storedVars['myarray'].length</td>
 +
<td></td>
 +
</tr>
 +
<tr>
 +
<td>open</td>
 +
<td>/Special:Upload</td>
 +
<td></td>
 +
</tr>
 +
<tr>
 +
<td>waitForPageToLoad</td>
 +
<td></td>
 +
<td></td>
 +
</tr>
 +
<tr>
 +
<td>storeEval</td>
 +
<td>index</td>
 +
<td>temp</td>
 +
</tr>
 +
<tr>
 +
<td>echo</td>
 +
<td>javascript{'/home/USER/CITY_'+storedVars['myarray'][storedVars['temp']]}</td>
 +
<td></td>
 +
</tr>
 +
<tr>
 +
<td>type</td>
 +
<td>id=wpUploadFile</td>
 +
<td>javascript{'/home/USER/CITY_'+storedVars['myarray'][storedVars['temp']]}</td>
 +
</tr>
 +
<tr>
 +
<td>click</td>
 +
<td>id=wpIgnoreWarning</td>
 +
<td></td>
 +
</tr>
 +
<tr>
 +
<td>clickAndWait</td>
 +
<td>name=wpUpload</td>
 +
<td></td>
 +
</tr>
 +
<tr>
 +
<td>getEval</td>
 +
<td>index++;</td>
 +
<td></td>
 +
</tr>
 +
<tr>
 +
<td>endWhile</td>
 +
<td></td>
 +
<td></td>
 +
</tr>
 +
</table>
 +
 
 +
    </div>
 +
    </div><!-- end accordion-section-content -->
 +
  </div><!-- end accordion-section -->
 +
</div> <!-- end accordion -->
 +
 
 +
<p>
 +
</p>
 +
 
 +
<div class="accordion">
 +
  <div class="accordion-section">
 +
    <a class="accordion-section-title" href="#accordion-3">HTML for Webserver-Input</a>
 +
    <div id="accordion-3" class="accordion-section-content" style="display:none; padding:15px;">
 +
      <div class="table sectionedit6">
 +
 
 +
     
 +
 
 +
&lt;form method=&quot;get&quot; action=&quot;wikitranslate.py&quot;&gt;<br/><br/> &lt;div&gt;<br/> &lt;h3&gt;Choose option:&lt;/h3&gt;<br/> &lt;input type=&quot;checkbox&quot; name=&quot;rmheaderlink&quot; value=&quot;True&quot;&gt;  Remove headerlinks&lt;br&gt;<br/> &lt;input type=&quot;checkbox&quot; name=&quot;changepicurl&quot; value=&quot;True&quot;&gt;  Change the picture links&lt;br&gt;<br/> &lt;input type=&quot;checkbox&quot; name=&quot;appendtextbefore&quot; value=&quot;True&quot;&gt;  Add preceding text &lt;br&gt;<br/> &lt;input type=&quot;checkbox&quot; name=&quot;appendtextafter&quot; value=&quot;True&quot;&gt;  Append text &lt;br&gt;<br/> &lt;input type=&quot;checkbox&quot; name=&quot;changeprotocols&quot; value=&quot;True&quot;&gt; Change protocol links &lt;br&gt;<br/> &lt;input type=&quot;checkbox&quot; name=&quot;changeregistry&quot; value=&quot;True&quot;&gt; Link registry entries &lt;br&gt;<br/> &lt;/div&gt;<br/> &lt;h3&gt;Provide information if necessary&lt;/h3&gt;<br/> &lt;div&gt;<br/> &lt;label for=&quot;dwhtml&quot;&gt;Name of an internal wiki-page (e.g. &lt;em&gt;labjournal:cellfree&lt;/em&gt;):&lt;/label&gt;<br/> &lt;input id=&quot;dwhtml&quot; name=&quot;dwsite&quot; required&gt;&lt;/textarea&gt;<br/> &lt;/div&gt;<br/> &lt;div&gt;<br/> &lt;label for=&quot;textbefore&quot;&gt;Text to precede&lt;/label&gt;<br/> &lt;textarea id='textbefore' cols=&quot;20&quot; rows=&quot;5&quot; name=&quot;textbefore&quot;&gt;<br/> {{Freiburg/CSS}}<br/> &lt;html&gt;<br/> &lt;/textarea&gt;  <br/> &lt;/div&gt;<br/> &lt;div&gt;<br/> &lt;label for=&quot;textafter&quot;&gt;Text to append&lt;/label&gt;<br/> &lt;textarea id=&quot;textafter&quot; cols=&quot;20&quot; rows=&quot;5&quot; name=&quot;textafter&quot;&gt;<br/> &lt;/html&gt;<br/> &lt;/div&gt;  <br/> &lt;div&gt;<br/> &lt;input type=&quot;submit&quot; value=&quot;Submit&quot;&gt;<br/> &lt;/div&gt;<br/><br/> &lt;/form&gt;
 +
 
 +
 +
 
 +
    </div>
 +
    </div><!-- end accordion-section-content -->
 +
  </div><!-- end accordion-section -->
 +
</div> <!-- end accordion -->
 +
 
 +
<p>
 +
</p>
 +
 
 +
<div class="accordion">
 +
  <div class="accordion-section">
 +
    <a class="accordion-section-title" href="#accordion-4">CGI script code to be run on Webserver</a>
 +
    <div id="accordion-4" class="accordion-section-content" style="display:none; padding:15px;">
 +
      <div class="table sectionedit6">
 +
     
 +
      #!/usr/bin/python<br/> import cgi<br/> form = cgi.FieldStorage() # instantiate only once!<br/><br/> dwsite = form.getfirst('dwsite', 'empty')<br/> #dwsite = 'labjournal:ilab'<br/><br/> isrmheaderlinks=form.getfirst('rmheaderlink', False)<br/> ischangepicurl=form.getfirst('changepicurl', False)<br/> appendtextbefore=form.getfirst('appendtextbefore', False)<br/> appendtextafter=form.getfirst('appendtextafter',  False)<br/> ischangeprotocols=form.getfirst('changeprotocols', False)<br/> isregistry=form.getfirst('changeregistry', False)<br/><br/> #isrmheaderlinks=True<br/> #ischangepicurl=True<br/> #appendtextbefore=True<br/> #appendtextafter=True<br/> #ischangeprotocols=True<br/> #isregistry=True<br/><br/> #textbefore='some text before'<br/> #textafter='some text after'<br/><br/> textbefore=form.getfirst('textbefore', '')<br/> textafter=form.getfirst('textafter', '')<br/><br/> # Avoid script injection escaping the user input<br/> dwsite = cgi.escape(dwsite)<br/><br/> from bs4 import BeautifulSoup # parse raw html and extract elements<br/> import urllib3 # read html-text from url<br/> import requests<br/> from requests.auth import HTTPBasicAuth<br/> import sys<br/> from cStringIO import StringIO<br/> import csv<br/> #import html <br/><br/> old_stdout = sys.stdout<br/> sys.stdout = mystdout = StringIO()<br/><br/> # read in the dict with internal and external protocol names<br/> protocolsdic = {}<br/> reader = csv.DictReader(open('protocols_names.csv', 'r'))<br/> for row in reader:<br/>     protocolsdic[row['internal']]=row['external']<br/>     <br/> # remove empty dict entries<br/> protocolsdic.pop('',  None)<br/><br/> # read in the dict with registry entries to replace<br/> registrydic = {}<br/> reader = csv.DictReader(open('registry_links.csv', 'r'))<br/> for row in reader:<br/>     registrydic[row['internal']]='&lt;a href=%(x)s&gt;%(y)s&lt;/a&gt;' % {'x' : '&quot;{}&quot;'.format(row['external']), 'y' : row['internal']}<br/><br/> ################<br/> # BEGIN DEFINITIONS <br/> ################<br/><br/> def getdwsource(dwsite):<br/>     # get the subsite of the internal wiki specified as site<br/>     # use the dummy usre to provide access to the wiki<br/>     dokuwiki=requests.get('https://wiki.uni-freiburg.de/igem2015/doku.php?id=%s&amp;do=export_xhtmlbody'%dwsite, auth=HTTPBasicAuth('dummy', 'igem2015'))<br/>     # extract the html of the requests-object by using beautifulsoup<br/>     soup=BeautifulSoup(dokuwiki.text,  'html.parser')<br/>     # print('https://wiki.uni-freiburg.de/igem2015/doku.php?id=%s&amp;do=export_xhtmlbody'%site)<br/>     return soup<br/><br/> def sfah(source):<br/> # return the soup-objects of all headers<br/> return source.findAll('h1') + source.findAll('h2') + source.findAll('h3') + source.findAll('h4') + source.findAll('h5') + source.findAll('h6')<br/><br/> def rmheaderlinks(soup):<br/>     ########<br/>     # removes the a-href links from the headers of an internal dw-file<br/>     ########<br/>     rmheaderlinksdic={}<br/>     for header in sfah(soup):<br/>     rmheaderlinksdic[unicode(header.a)]=header.a.text<br/>     return rmheaderlinksdic<br/><br/> def getdwpicnames(source):<br/>     ########<br/>     # returns a dict of the the names of all images in the source code as keys with the corresponding links to the image and the info-page<br/>     ########<br/>     picnamesdic={}<br/>     for img in source.find_all('img'):<br/>         # extract the name of all pictures from the src-string<br/>         try:<br/>             # get the name of the picnamesdic<br/>             dwname=img.get('src').split('media=')[1]<br/>             # use the name as key for a dict to store the links for src and href<br/>             picnamesdic[dwname]=[img.get('src')]<br/>             picnamesdic[dwname].append(img.parent.get('href'))<br/>             print('+ \t %s '%img.get('src').split('media=')[1])<br/>             # print('dwlink=%s'%picnamesdic[dwname])<br/>         except:<br/>             print('- \t\t %s '%img.get('src').split('/')[-1])<br/>     return picnamesdic<br/>     <br/> def getpicurl(picname):<br/>     # input: The name of a file uploaded on the iGEM 2015 Wiki-Server #<br/>     # IMPORTANT: The picture has to be uploaded before running the script! #<br/>     # picname=input('please paste the name of an uploaded iGEM-wiki file:\n')<br/>     <br/>     # correct picname for changes the iGEM-Server needs<br/>     picname=picname.replace(':','-' )<br/>     <br/>     # define fix url for Wiki-Sever #<br/>     url='https://2015.igem.org/File:Freiburg_%s'%picname<br/>     #print('the url I looked for was:\n%s' %url)<br/>     <br/>     # get raw_html from url as specified here: http://stackoverflow.com/questions/17257912/how-to-print-raw-html-string-using-urllib3 #<br/>     <br/>     http_pool = urllib3.connection_from_url(url)<br/>     r = http_pool.urlopen('GET',url)<br/>     raw_html=r.data.decode('utf-8')<br/>     <br/>     # initialise bs-object '<br/>     soup = BeautifulSoup(raw_html, 'html.parser')<br/>     <br/>     # find the href-link in an a-object in a div with id=file #<br/>     try:<br/>         serverlink='https://2015.igem.org'+soup.find(id='file').find('a').get('href')<br/>         # return the link #<br/>         return serverlink<br/>     except:<br/>         return None<br/>         <br/> def unescape(s):<br/>     s = s.replace(&quot;&amp;lt;&quot;, &quot;&lt;&quot;)<br/>     s = s.replace(&quot;&amp;gt;&quot;, &quot;&gt;&quot;)<br/>     # this has to be last:<br/>     s = s.replace(&quot;&amp;amp;&quot;, &quot;&amp;&quot;)<br/>     return s<br/><br/> def changeprotocols(soup):<br/>     returndic = {}<br/>     for link in soup.findAll('a'):<br/>         linksource = link.get('href')<br/>         for name in protocolsdic:<br/>             if linksource != None:<br/>                 if unicode(name) in linksource :<br/>                     print(unicode(name))<br/>                 # generate pairs for replacement using the absolute path for the iGEM server protocols section<br/>                     returndic[linksource] =unicode('https://2015.igem.org/Team:Freiburg/Protocols/')+protocolsdic[name]<br/>     return returndic<br/><br/><br/> ##########################<br/> # BEGIN PROGRAMME<br/> ##########################<br/><br/> # set the subprogramcounter<br/> prog_count = 0<br/><br/> # get the source code<br/> dwsource=getdwsource(dwsite)<br/><br/> # convert it to replaceable text<br/> exthtml=unicode(dwsource)<br/><br/> # initialize dic to replace elements<br/> rpdic={}<br/><br/> ### is rmheaderlinks ###<br/> if isrmheaderlinks:<br/> # compute dic to replace headerlinks<br/> rpdic.update(rmheaderlinks(dwsource))<br/>         prog_count+=1<br/><br/> ### is changeprotocols ###<br/> if ischangeprotocols:<br/>     rpdic.update(changeprotocols(dwsource))<br/>     prog_count+=1<br/><br/> ### is changepicurl ###<br/> missingimage = False<br/><br/> if ischangepicurl:<br/>     picnamesdic=getdwpicnames(dwsource)<br/>     for key in picnamesdic:<br/>         serverlink=getpicurl(key)<br/>         if serverlink != None:<br/>             rpdic.update({cgi.escape(picnamesdic[key][0]):serverlink})<br/>         else:<br/>             missingimage = True<br/> if picnamesdic[key][1]:<br/>         rpdic.update({cgi.escape(picnamesdic[key][1]):serverlink})<br/>     prog_count+=1<br/><br/> ### is registry ###<br/> if isregistry:<br/>     rpdic.update(registrydic)<br/>     prog_count+=1<br/>         <br/> ### cancel output if no program was called ###<br/> if prog_count == 0:<br/>     sys.exit(0)<br/><br/> ### replacing ###<br/> exthtmlold = exthtml<br/> for text in rpdic.keys():<br/> #    exthtml = exthtml.replace(cgi.escape(text),unescape(rpdic[text]))<br/>     exthtml = exthtml.replace(text,rpdic[text])<br/><br/> sys.stdout=old_stdout<br/><br/> if not missingimage:<br/><br/>     print &quot;Content-Disposition: attachment; filename=\&quot;%s.html\&quot;\r\n\n&quot;%dwsite<br/><br/>     if appendtextbefore:<br/>     print(textbefore.encode('utf8'))<br/>     print(exthtml.encode('utf8'))<br/>     if appendtextafter:<br/>     print(textafter.encode('utf8'))<br/> else:<br/>     print &quot;Content-type: text/html \n&quot;<br/><br/>     print('There is an image missing!!')
 +
     
 +
    </div>
 +
    </div><!-- end accordion-section-content -->
 +
  </div><!-- end accordion-section -->
 +
</div> <!-- end accordion -->
 +
 
 +
 
 +
 
 +
<div class="tags">
 +
<span>
 
<a class="wikilink1" href="/igem2015/doku.php?id=tag:info&amp;do=showtag&amp;tag=info" rel="tag" title="tag:info">info</a>
 
<a class="wikilink1" href="/igem2015/doku.php?id=tag:info&amp;do=showtag&amp;tag=info" rel="tag" title="tag:info">info</a>
</span></div>
+
</span>
 +
</div>
 
</div>
 
</div>
 
<!-- EDIT5 SECTION "Script-Code" [4227-] -->
 
<!-- EDIT5 SECTION "Script-Code" [4227-] -->

Latest revision as of 01:30, 19 September 2015

""

How to Migrate to the iGEM-Wiki: The Freiburg Way

At the end of an iGEM summer writing the final wiki in time for wiki freeze is a challenge every iGEM team experiences. But apart from designing the wiki itself, using CSS and Javascript, a main problem is the content. A final iGEM wiki should on the one hand be good to read and inspire people for science, on the other hand all the information needed to repeat the experiments has to be provided for good scientific practice. And especially for this last aspect we would like to show how we worked on our wiki and what may be adaptable for future teams.

The Internal Wiki

To start early and to document every step we did, we worked with a so called internal wiki that was based on dokuwiki and hosted on the university's web server. A special advantage of this wiki-system was an introductory course provided by the university and the relatively simple formatting syntax that allowed direct work without long learning periods. Additionally the wiki is used to organize our team, to protocol meetings and to provide information such as scientific papers and protocols as well as cooking recipes that we tested during these meetings. But a major drawback from using dokuwiki was that the syntax is not at all compatible with the mediawiki syntax that is used on the external official iGEM wiki. To not rewrite all articels we thought for a solution to convert content between these wikis in a fast and simple way.

Migration

Form providing input for the wikitranslate script

Even though the dokuwiki provides a feature to export the page's body content (by appending &do=export_xhtmlbody to the URL and getting the source code of this via STRG+U in Firefox) all the image links refer to the internal server and are, therefore, broken. The first step in migrating our content, thus was a script to download all the images of a specified internal wiki page and prefix the file names with Freiburg_ to avoid name conflicts with other teams. The program also outputs a file with all the file names separated by commas that is later used to upload the files. To transfer the downloaded and renamed files onto the iGEM server the selenium browser automation tool (http://www.seleniumhq.org/) in combination with the sideflow-plugin (https://github.com/73rhodes/sideflow) was used. This plugin allows for the creation of loops in selenium routines as needed to upload a list of files. The steps in the selenium routine are basically the coded equivalent to clicking on the upload-button, selecting a file, clicking the ignore any warnings button and submit the form. Once the files are on the server, it is necessary to get their location on this server to use it as image source in the html-text on the sites. As the iGEM Server assigns a variable path to every file (as /e/e4/filename.png) this path has to be probed for every single image to be used on the site. This routine is implemented in the wikitranslate script together with a routine for replacing the linked headers by unlinked ones and one for adding preceding and following text, such that, for example custom styling for a specific page can be done directly in the protocol. The script is used on a web server basis (as cgi - script) and thus can be used by every team member with no needs for programming skills. It then returns an html-file that contains the source code to paste in the manually created new external wiki page.

Refining the External Wiki

Despite lowering a lot the workload needed for transferring our content to the external wiki, there still is need to adapt the design by hand. A major aspect here is a consistent design of the uploaded pages with the ones created especially for the external wiki, as the landing page or the project overview pages. All in all, using an automated uploading and replacing procedure to transfer our content from the internal to the external wiki allowed us to spend more time on the remaining pages, like our poster and the presentation. And we hope that our experiences might also be useful for other teams writing their content in advance.

Script-Code

dwfileload.py:

Presets for Selenium IDE

HTML for Webserver-Input

CGI script code to be run on Webserver