<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>robots.txt</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -19,3 +19,7 @@ handlers:
 - url: /favicon.ico
   static_files: images/favicon.ico
   upload: images/favicon.ico
+
+- url: /robots.txt
+  static_files: robots.txt
+  upload: robots.txt</diff>
      <filename>app.yaml</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,7 @@ import utils
 class User(db.Model):
   google_user = db.UserProperty(required=True)
   date_created = db.DateTimeProperty(auto_now_add=True)
-  nickname = db.StringProperty(required=True)
+  nickname = db.TextProperty(required=True)
   
   def playlists(self):
     return (x for x in self.library_set.order(&quot;position&quot;))
@@ -19,14 +19,20 @@ class User(db.Model):
   
   def re_index_playlists(self):
     i = 0
+    entities_to_update = []
     for p in self.playlists():
       p.position = i
-      p.put()
+      entities_to_update.append(p)
       i+=1
-  
+    db.put(entities_to_update)
+    
   def last_lib_position(self):
-    q = db.GqlQuery(&quot;SELECT * FROM Library WHERE user = :user ORDER BY position DESC&quot;, user=self)  
-    return q.get().position
+    q = db.GqlQuery(&quot;SELECT * FROM Library WHERE user = :user ORDER BY position DESC&quot;, user=self)
+    p = q.get()
+    if p:
+      return p.position
+    else:
+      return -1
     
   
   def re_sort_playlists(self, library_item, new_position):
@@ -40,16 +46,17 @@ class User(db.Model):
       library_item.put()
       
     elif library_item.position &gt; new_position: #Moved up
+      entities_to_update = []
       for p in playlists:
         if (p.position &lt; library_item.position and (p.position &gt; new_position or p.position == new_position)):
           p.position += 1
-          p.put() 
+          entities_to_update.append(p)
       library_item.position = new_position
-      library_item.put()
-      
+      entities_to_update.append(library_item)
+      db.put(entities_to_update)
 
 class Playlist(db.Model):
-  name = db.StringProperty(required=True, default='Playlist')
+  name = db.TextProperty(required=True, default='Playlist')
   date_created = db.DateTimeProperty(auto_now_add=True)
   collaborative = db.BooleanProperty(default=False)  
   tracks = db.TextProperty(default=&quot;0&quot;)</diff>
      <filename>models.py</filename>
    </modified>
    <modified>
      <diff>@@ -433,7 +433,7 @@ SC.Playlist.prototype = {
   },
   addToPlaylistsList: function() { // add the tab for the playlist
     var self = this;
-    $(&quot;&lt;li listId='&quot; + this.id + &quot;' class='&quot; + (this.properties.is_owner ? &quot;&quot; : &quot;shared&quot;) + &quot; &quot; + (this.properties.playlist.collaborative ? &quot;collaborative&quot; : &quot;&quot;) + &quot; &quot; + (this.persisted ? &quot;&quot; : &quot;dont-persist&quot;) + &quot; &quot; + (this.properties.playlist.smart ? &quot;smart&quot; : &quot;&quot;) + &quot; &quot; + (this.properties.playlist.search ? &quot;search&quot; : &quot;&quot;) + &quot;'&gt;&lt;span&gt;&lt;/span&gt;&lt;a href='#'&gt;&quot; + this.name + (this.properties.is_owner ? &quot;&quot; : &quot; &lt;em&gt;by &quot; + this.properties.playlist.owner.nickname + &quot;&lt;/em&gt;&quot;) + &quot;&lt;/a&gt;&lt;a class='collaborative' title='Make Playlist Collaborative' href='/playlists/&quot; + this.id + &quot;'&gt;&amp;nbsp;&lt;/a&gt;&lt;a class='share' title='Share Playlist' href='/share/&quot; + this.properties.playlist.share_hash + &quot;'&gt;&amp;nbsp;&lt;/a&gt;&lt;a class='delete' title='Remove Playlist' href='/playlists/&quot; + this.id + &quot;'&gt;&amp;nbsp;&lt;/a&gt;&lt;/li&gt;&quot;)
+    $(&quot;&lt;li listId='&quot; + this.id + &quot;' class='&quot; + (this.properties.is_owner ? &quot;&quot; : &quot;shared&quot;) + &quot; &quot; + (this.properties.playlist.collaborative ? &quot;collaborative&quot; : &quot;&quot;) + &quot; &quot; + (this.persisted ? &quot;&quot; : &quot;dont-persist&quot;) + &quot; &quot; + (this.properties.playlist.smart ? &quot;smart&quot; : &quot;&quot;) + &quot; &quot; + (this.properties.playlist.search ? &quot;search&quot; : &quot;&quot;) + &quot;'&gt;&lt;span&gt;&lt;/span&gt;&lt;a href='#'&gt;&quot; + this.name + (this.properties.is_owner ? &quot;&quot; : &quot; &lt;em&gt;by &quot; + this.properties.playlist.owner.nickname + &quot;&lt;/em&gt;&quot;) + &quot;&lt;/a&gt;&lt;a class='collaborative' title='Make Playlist Collaborative' href='/playlists/&quot; + this.id + &quot;'&gt;&amp;nbsp;&lt;/a&gt;&lt;a class='share' title='Share Playlist' href='/share/playlist/&quot; + this.properties.playlist.share_hash + &quot;'&gt;&amp;nbsp;&lt;/a&gt;&lt;a class='delete' title='Remove Playlist' href='/playlists/&quot; + this.id + &quot;'&gt;&amp;nbsp;&lt;/a&gt;&lt;/li&gt;&quot;)
       .find('a:first').click(function(ev) {
         if($(this).parents(&quot;li&quot;).hasClass(&quot;active&quot;) &amp;&amp; self.properties.is_owner &amp;&amp; $(&quot;body&quot;).hasClass(&quot;logged-in&quot;)) {
           var that = this; // very strange that i can't use self here</diff>
      <filename>scripts/playlist.js</filename>
    </modified>
    <modified>
      <diff>@@ -49,7 +49,7 @@ class SharePlaylist(webapp.RequestHandler):
       if users.get_current_user() and not app_user:
         app_user = utils.init_new_user()
         
-      share_hash = utils.url_to_entity_key(self.request.uri)
+      share_hash = utils.url_to_share_key(self.request.uri)
       q = db.GqlQuery(&quot;SELECT * FROM Playlist WHERE share_hash = :share_hash&quot;, share_hash=share_hash)  
       playlist = q.get()
 
@@ -65,6 +65,24 @@ class SharePlaylist(webapp.RequestHandler):
       
       self.redirect(&quot;/?flash=&quot;+flash)
         
+class ShareTrack(webapp.RequestHandler):
+  def get(self):
+    if not users.get_current_user():
+      self.redirect(users.create_login_url(self.request.uri)) 
+    else:      
+      app_user = utils.get_current_user()
+      if users.get_current_user() and not app_user:
+        app_user = utils.init_new_user()
+
+      track_id = utils.url_to_share_key(self.request.uri)
+      
+      playlist = models.Playlist(name = &quot;Untitled&quot;, owner=app_user, tracks=track_id + &quot;, &quot;, share_hash = utils.generate_share_hash())
+      playlist.put()
+    
+      library_item = models.Library(user=app_user, playlist=playlist, is_owner=True, position = app_user.last_lib_position()+1)
+      library_item.put()
+      self.redirect(&quot;/&quot;)
+
 class Playlist(webapp.RequestHandler):  
   def get(self):
     key = utils.url_to_entity_key(self.request.uri)
@@ -84,7 +102,7 @@ class Playlist(webapp.RequestHandler):
     if method == &quot;PUT&quot;:
     
       if library_item.is_owner: #A bit special, does not need version handling
-        if(self.request.get('name') &amp;&amp; len(self.request.get('name')) &gt; 0  ):
+        if(self.request.get('name') and len(self.request.get('name')) &gt; 0  ):
           playlist.name = utils.strip_html(self.request.get('name'))
           playlist.put()
       
@@ -143,6 +161,7 @@ class Playlists(webapp.RequestHandler):
       utils.parse_smart_filters(playlist, self.request)
     
     playlist.put()
+    
     library_item = models.Library(user=current_user, playlist=playlist, is_owner=True, position = int(self.request.get(&quot;position&quot;)))
     library_item.put()
     
@@ -154,7 +173,8 @@ def main():
                                       ('/playlists/', Playlists), 
                                       ('/playlists/.*', Playlist), 
                                       ('/user', User), 
-                                      ('/share/.*', SharePlaylist), 
+                                      ('/share/playlist/.*', SharePlaylist), 
+                                      ('/share/track/.*', ShareTrack), 
                                       ('/', PlayerPage)
                                       ], debug=True)
   run_wsgi_app(application)</diff>
      <filename>the-cloud-player.py</filename>
    </modified>
    <modified>
      <diff>@@ -47,6 +47,14 @@ def url_to_entity_key(url):
   else:
     return &quot;&quot;
 
+def url_to_share_key(url):
+  url_array = url.split(&quot;/&quot;)
+  if len(url_array) &gt; 5:
+    return url_array[5]
+  else:
+    return &quot;&quot;
+
+
 def convert_javascript_bool_to_python(s):
   if s.lower() == &quot;true&quot;:
     return True
@@ -111,4 +119,4 @@ def parse_smart_filters(playlist, request):
   return playlist
 
 def strip_html(s):
-  return re.replace('&lt;.*?&gt;', '', s)    
\ No newline at end of file
+  return re.sub('&lt;.*?&gt;', '', s)    
\ No newline at end of file</diff>
      <filename>utils.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>96b371a884d29e93654bc7bd69389c93f35dbeb6</id>
    </parent>
  </parents>
  <author>
    <name>Henrik Berggren</name>
    <email>hinke@hinkeb.com</email>
  </author>
  <url>http://github.com/hinke/the-cloud-player/commit/cbb6d63c9dac1fa0a9f7617072ce1d7da4bd8da4</url>
  <id>cbb6d63c9dac1fa0a9f7617072ce1d7da4bd8da4</id>
  <committed-date>2008-12-06T11:15:31-08:00</committed-date>
  <authored-date>2008-12-06T11:15:31-08:00</authored-date>
  <message>Added robots.txt + static url, added single track sharing, optimized sorting storing and some smaller overall improvements</message>
  <tree>f02ff40e31621395871345857cc7a8b71c30fabe</tree>
  <committer>
    <name>Henrik Berggren</name>
    <email>hinke@hinkeb.com</email>
  </committer>
</commit>
