1. Ye Liu
  2. SkypieaMC

Commits

jaux  committed 32fd515

Added account controller, implemented FileController.delete()

No authentication and authorization yet

  • Participants
  • Parent commits 70d1f6f
  • Branches default

Comments (0)

Files changed (15)

File skypieamc/config/routing.py

View file
 
     # CUSTOM ROUTES HERE
 
-    map.connect('tagged_files', '/file/list/{tagid}',
-                controller='file', action='list')
     map.connect('/{controller}/{action}')
     map.connect('/{controller}/{action}/{id}')
     map.connect('root', '/', controller='file', action='list');

File skypieamc/controllers/account.py

View file
+import logging
+
+from pylons import request, response, session, tmpl_context as c
+from pylons.controllers.util import abort, redirect_to
+
+from sqlalchemy import and_, delete, desc
+from webhelpers import paginate
+
+from skypieamc import model
+from skypieamc.lib.base import BaseController, render
+from skypieamc.model import meta
+
+log = logging.getLogger(__name__)
+
+class AccountController(BaseController):
+
+    def list(self, id=None):
+        files = meta.Session.query(model.File).\
+            order_by(desc(model.File.uploaded))
+        c.paginator = paginate.Page(
+            files,
+            page=request.params.get('page', 1),
+            items_per_page=10,
+            controller='account',
+            action='list'
+        )
+        c.tags = meta.Session.query(model.Tag).all()
+        return render('/derived/account/list.mako')

File skypieamc/controllers/file.py

View file
 from formencode.validators import FieldStorageUploadConverter, \
                                   FancyValidator, String
 from mimetypes import guess_type
-from sqlalchemy import desc, and_
+from sqlalchemy import and_, delete, desc
 from webhelpers import paginate
 
 from skypieamc import model
 
 log = logging.getLogger(__name__)
 
-class ValidTagsString(FancyValidator):
+class TagsConverter(FancyValidator):
+
+    def __init__(self, create_if_not_exist=False, *args, **kwargs):
+        super(TagsConverter, self).__init__(*args, **kwargs)
+        self._create_if_not_exist = create_if_not_exist
 
     def _to_python(self, value, state):
         value = String().to_python(value, state)
         tag_names = filter(None, re.compile('[, ]+').split(value))
 
         def find_tag(tname):
+            tname = tname.lower()
             tag = meta.Session.query(model.Tag).filter_by(name=tname).first()
-            if tag is None:
+            if tag is None and self._create_if_not_exist:
                 tag = model.Tag()
                 tag.name = tname
                 meta.Session.add(tag)
                 meta.Session.commit()
             return tag
 
-        return map(find_tag, tag_names)
+        if self._create_if_not_exist:
+            return map(find_tag, tag_names)
+        else:
+            return filter(map(find_tag, tag_names), None)
 
 class UploadForm(Schema):
 
         not_empty=True,
         messages={'empty': u'Please specify a file to upload.'}
     )
-    tags = ValidTagsString();
+    tags = TagsConverter(create_if_not_exist=True);
+
+class SearchForm(Schema):
+
+    allow_extra_fields = True
+    filter_extra_fields = True
+    search_tags = TagsConverter()
 
 class FileController(BaseController):
 
-    def __before__(self):
-        c.tags = meta.Session.query(model.Tag).all()
-
-    def list(self, tagid=None):
+    def list(self):
         files = meta.Session.query(model.File).\
             order_by(desc(model.File.uploaded))
-        if tagid:
-            files = files.filter(
-                and_(model.file_tag_table.c.fileid == model.File.id,
-                     model.file_tag_table.c.tagid == tagid)
-            )
         c.paginator = paginate.Page(
             files,
             page=request.params.get('page', 1),
             controller='file',
             action='list'
         )
+        c.tags = meta.Session.query(model.Tag).all()
         return render('/derived/file/list.mako')
 
+    @validate(schema=SearchForm(), form='list')
+    def search(self, id=None):
+        """
+        Search files tagged by the tagid
+        
+        tagid -- int/str/unicode
+        """
+        files = meta.Session.query(model.File).\
+            order_by(desc(model.File.uploaded))
+        if id:
+            tmp = files.filter(
+                and_(model.file_tag_table.c.fileid == model.File.id,
+                     model.file_tag_table.c.tagid == id)
+            )
+            if tmp.count() > 0:
+                files = tmp
+            else:
+                session['flash_msg'] = u'No results have been found!'
+                session.save()
+        c.paginator = paginate.Page(
+            files,
+            page=request.params.get('page', 1),
+            items_per_page=10,
+            controller='file',
+            action='search'
+        )
+        c.tags = meta.Session.query(model.Tag).all()
+        return render('/derived/file/list.mako')
+        
     def upload(self):
         return render('/derived/file/upload.mako')
 
         c.play_url = h.url_for(controller='file', action='download', id=id)
         c.play_url += '?playable'
         return render('/derived/file/play.mako')
+
+    def delete(self, id=None):
+        """
+        Delete the file specified by id
+        
+        id -- int/str/unicode
+        """
+        mfile = id and meta.Session.query(model.File).get(id)
+        if mfile is None:
+            abort(404, u'File not found')
+        meta.Session.execute(delete(model.file_tag_table,
+                                    model.file_tag_table.c.fileid == id))
+        meta.Session.delete(mfile)
+        meta.Session.commit()
+        session['flash_msg'] = u'"{0}" has been deleted!'.format(mfile.name)
+        session.save()
+        return redirect_to(controller='account', action='list')

File skypieamc/public/css/list.css

View file
   background-image: url('/images/icon_download.png');
 }
 
+#file-list .btn_edit {
+  background-image: url('/images/icon_edit.png');
+}
+
+#file-list .btn_delete {
+  background-image: url('/images/icon_delete.png');
+}
+
 #file-list .btn_play,
-#file-list .btn_download {
+#file-list .btn_download,
+#file-list .btn_edit,
+#file-list .btn_delete {
   display: block;
   background-repeat: no-repeat;
   background-position: top left;
   font-size: 116%;
   text-decoration: underline;
 }
+
+#tags h2 {
+  color: #7A2433;
+  font-size: 167%;
+  font-weight: bold;
+  margin-bottom: 10px;
+}
+
+#tags a {
+  color: #7A2433;
+  font-weight: bold;
+}
+

File skypieamc/public/css/main.css

View file
   margin-bottom: 10px;
 }
 
-#tags h2 {
-  color: #7A2433;
-  font-size: 167%;
-  font-weight: bold;
-  margin-bottom: 10px;
-}
-
-#tags a {
-  color: #7A2433;
-  font-weight: bold;
-}
-
 /** footer **/
 
 #ft {
 }
 
 .small {
-  font-size: 85%;
+  font-size: 100%;
+}
+
+.median {
+  font-size: 153.9%;
 }
 
 .big {
-  font-size: 189%;
+  font-size: 197%;
 }

File skypieamc/public/css/upload.css

View file
   padding-top: 10px;
 }
 
-#status #text {
+#status .text {
+  display: inline;
   color: #7A2433;
   font-size: 108%;
   font-weight: bold;
   position: relative;
   top: -10px;
 }
+
+#tips h2 {
+  color: #7A2433;
+  font-size: 167%;
+  font-weight: bold;
+  margin-bottom: 10px;
+}
+
+#tips ol li {
+  background: url('/images/bullet_orange.png') no-repeat;
+  padding: 0 0 5px 16px;
+  color: #7A2433;
+}

File skypieamc/public/images/bullet_orange.png

Added
New image

File skypieamc/public/images/icon_delete.png

Added
New image

File skypieamc/public/images/icon_edit.png

Added
New image

File skypieamc/public/js/upload.js

View file
 SMC.Y.use('io-upload-iframe', 'json-parse', function(Y) {
     var status_img = Y.one('#status img');
-    var status_text = Y.one('#status #text');
+    var status_text = Y.one('#status p');
     function onStart(id, args) {
       status_img.setAttribute('src', '/images/ajax-loader.gif');
       status_text.setContent('Uploading file...');
         var resp = Y.JSON.parse(o.responseText);
         if (resp.status) {
           status_img.setAttribute('src', '/images/icon_accept.png');
-          status_text.setContent('"' + resp.file_name + '"' + ' uploaded successfully!');
+          status_text.setContent(
+            '"' + resp.file_name + '"' + ' uploaded successfully! <a href="/">Go back?</a>'
+          );
         }
         else {
           status_img.setAttribute('src', '/images/icon_block.png');

File skypieamc/templates/base.mako

View file
       <h1>${h.link_to('SkypieaMC', h.url_for('root'))}</h1>
     </div>
     <div class="yui-u">
+      <%doc>
       <div id="login">
         ${h.link_to('Login', h.url_for(''))}
         | ${h.link_to('Sign up', h.url_for(''))}
       </div>
+      </%doc>
     </div>
   </div>
 </%def>
 
 <%def name="flash_message()">
   %if session.has_key('flash_msg'):
-    <div id="flash-msg"><p>${session['flash_msg']}</p></div>
+    <div id="flash-msg"><p>${session['flash_msg'].encode('utf-8')}</p></div>
     <%
       del session['flash_msg']
       session.save()
 
 <%def name="sidebar()">
   <div id="sidebar">
-    <div id="tags">
-      <h2>Tags:</h2>
-      <p>
-        %if len(c.tags) > 0:
-          %for tag in c.tags:
-            <%
-              font_size = 'small'
-              if tag.file_count >= 10:
-                font_size = 'big'
-              elif tag.file_count >= 5:
-                font_size = 'normal'
-            %>
-            ${h.link_to(
-                tag.name.encode('utf-8'),
-                h.url_for('tagged_files', tagid=tag.id),
-                class_=font_size
-              )}
-          %endfor
-        %else:
-          No tags have been created yet.
-        %endif
-      </p>
-    </div>
+    ${next.sidebar()}
   </div>
 </%def>
 

File skypieamc/templates/derived/account/list.mako

View file
+<%inherit file="/derived/file/list.mako" />
+
+<%def name="actions(mfile)">
+  <td class="button">
+    <a class="btn_edit"
+       href="${h.url_for(controller='file', action='edit', id=mfile.id)}">
+      <span class="text">Edit</span>
+    </a>
+  </td>
+  <td class="button">
+    <a class="btn_delete"
+       href="${h.url_for(controller='file', action='delete', id=mfile.id)}">
+      <span class="text">Delete</span>
+    </a>
+  </td>
+</%def>
+
+<%def name="addon_content(mfile)"></%def>

File skypieamc/templates/derived/file/list.mako

View file
     %for f in c.paginator:
       <tr id="${f.id}" class="${'odd' if count % 2 else 'even'}">
         <td class="file-info">${self.file_info(f)}</td>
-        <td class="button">${self.btn_play(f)}</td>
-        <td class="button">${self.btn_download(f)}</td>
+        ${self.actions(f)}
       </tr>
-      %if f.playable is not None:
-        <tr id="player_container-${f.id}" class="player-container hidden">
-          <td colspan="3">
-            ${h.link_to(
-                f.name.encode('utf-8'), 
-                h.url_for(controller='file',
-                          action='download',
-                          id=f.id,
-                          playable='true'),
-                id='player-{0}'.format(f.id))}
-          </td>
-        </tr>
-      %endif
+      ${self.addon_content(f)}
       <% count += 1 %>
     %endfor
   </table>
           %for tag in mfile.tags[:3]:
             ${h.link_to(
                 tag.name.encode('utf-8'),
-                h.url_for('tagged_files', tagid=tag.id)
+                h.url_for(controller='file', action='search', id=tag.id)
               )}
           %endfor
         </span></div>
 <%def name="mime_icon(fname)">
   ${h.image(h.url_for('/images/icon_{0}.png'.format(h.file_type(fname))), None)}
 </%def>
+<%def name="actions(mfile)">
+  <td class="button">
+    %if mfile.playable is not None:
+      <a class="btn_play"
+         href="${h.url_for(controller='file', action='play', id=mfile.id)}">
+        <span class="text">Play</span>
+      </a>
+    %endif
+  </td>
+  <td class="button">
+    <a class="btn_download"
+       href="${h.url_for(controller='file', action='download', id=mfile.id)}">
+      <span class="text">Download</span>
+    </a>
+  </td>
+</%def>
 
-<%def name="btn_play(mfile)">
+<%def name="addon_content(mfile)">
   %if mfile.playable is not None:
-    <a class="btn_play"
-       href="${h.url_for(controller='file', action='play', id=mfile.id)}">
-      <span class="text">Play</span>
-    </a>
+    <tr id="player_container-${mfile.id}" class="player-container hidden">
+      <td colspan="3">
+        ${h.link_to(
+            mfile.name.encode('utf-8'), 
+            h.url_for(controller='file',
+                      action='download',
+                      id=mfile.id,
+                      playable='true'),
+            id='player-{0}'.format(mfile.id))}
+      </td>
+    </tr>
   %endif
 </%def>
 
-<%def name="btn_download(mfile)">
-  <a class="btn_download"
-     href="${h.url_for(controller='file', action='download', id=mfile.id)}">
-    <span class="text">Download</span>
-  </a>
+<%def name="sidebar()">
+  <div id="tags">
+    <h2>Tags:</h2>
+    <p>
+      %if len(c.tags) > 0:
+        %for tag in c.tags:
+          <%
+            font_size = 'small'
+            if tag.file_count >= 10:
+              font_size = 'big'
+            elif tag.file_count >= 5:
+              font_size = 'median'
+          %>
+          ${h.link_to(
+              tag.name.encode('utf-8'),
+              h.url_for(controller='file', action='search', id=tag.id),
+              class_=font_size
+            )}
+        %endfor
+      %else:
+        No tags have been created yet.
+      %endif
+    </p>
+  </div>
 </%def>

File skypieamc/templates/derived/file/upload.mako

View file
 
 <div id="status">
   ${h.image(h.url_for('/images/icon_info.png'), alt="")}
-  <span id="text">Please select a file to upload!</span>
+  <p class="text">Please select a file to upload!</p>
 </div>
+
+<%def name="sidebar()">
+  <div id="tips">
+    <h2>Tips:</h2>
+    <ol>
+      <li>
+        <p>Separate tags by commas or spaces</p>
+      </li>
+      <li>
+        <p>It will take a while to convert media files to playalbe</p>
+      </li>
+    </ol>
+  </div>
+</%def>

File skypieamc/tests/functional/test_account.py

View file
+from skypieamc.tests import *
+
+class TestAccountController(TestController):
+
+    def test_index(self):
+        response = self.app.get(url(controller='account', action='index'))
+        # Test response...