Clean up & Add support to update objects in feed API
authorJessica Tallon <jessica@megworld.co.uk>
Tue, 8 Jul 2014 20:27:43 +0000 (21:27 +0100)
committerJessica Tallon <jessica@megworld.co.uk>
Tue, 22 Jul 2014 22:13:15 +0000 (23:13 +0100)
mediagoblin/federation/views.py
mediagoblin/oauth/oauth.py

index 1e8c3e14bd4238ed5b71707707af3bdb540c91da..8af5565bd577eccd2f9d86d7ddab60f3ae29011c 100644 (file)
@@ -64,7 +64,7 @@ def uploads(request):
         file_data = FileStorage(
             stream=io.BytesIO(request.data),
             filename=filename,
-            content_type=request.headers.get("Content-Type", "application/octal-stream")
+            content_type=mimetype
         )
 
         # Find media manager
@@ -90,9 +90,12 @@ def feed(request):
         return json_response({"error": error}, status=404)
 
     request.user = requested_user[0]
-
-    if request.method == "POST":
+    if request.data:
         data = json.loads(request.data)
+    else:
+        data = {"verb": None, "object": {}}
+
+    if request.method == "POST" and data["verb"] == "post":
         obj = data.get("object", None)
         if obj is None:
             error = {"error": "Could not find 'object' element."}
@@ -139,12 +142,74 @@ def feed(request):
             error = {"error": error_message}
             return json_response(error, status=400)
 
+    elif request.method in ["PUT", "POST"] and data["verb"] == "update":
+        # Check we've got a valid object
+        obj = data.get("object", None)
+
+        if obj is None:
+            error = {"error": "Could not find 'object' element."}
+            return json_response(error, status=400)
+
+        if "objectType" not in obj:
+            error = {"error": "No objectType specified."}
+            return json_response(error, status=400)
+
+        if "id" not in obj:
+            error = {"error": "Object ID has not been specified."}
+            return json_response(error, status=400)
+
+        obj_id = obj["id"]
+
+        # Now try and find object
+        if obj["objectType"] == "comment":
+            comment = MediaComment.query.filter_by(id=obj_id)
+            if comment is None:
+                error = {"error": "No such 'comment' with id '{0}'.".format(obj_id)}
+                return json_response(error, status=400)
+            comment = comment[0]
+
+            # TODO: refactor this out to update/setting method on MediaComment
+            if obj.get("content", None) is not None:
+                comment.content = obj["content"]
+
+            comment.save()
+            activity = {
+                "verb": "update",
+                "object": comment.serialize(request),
+            }
+            return json_response(activity)
+
+        elif obj["objectType"] == "image":
+            image = MediaEntry.query.filter_by(id=obj_id)
+            if image is None:
+                error = {"error": "No such 'image' with the id '{0}'.".format(obj_id)}
+                return json_response(error, status=400)
+
+            image = image[0]
+
+            # TODO: refactor this out to update/setting method on MediaEntry
+            if obj.get("displayName", None) is not None:
+                image.title = obj["displayName"]
+
+            if obj.get("content", None) is not None:
+                image.description = obj["content"]
+
+            if obj.get("license", None) is not None:
+                # I think we might need some validation here
+                image.license = obj["license"]
+
+            image.save()
+            activity = {
+                "verb": "update",
+                "object": image.serialize(request),
+            }
+            return json_response(activity)
 
     feed_url = request.urlgen(
-            "mediagoblin.federation.feed",
-            username=request.user.username,
-            qualified=True
-            )
+        "mediagoblin.federation.feed",
+        username=request.user.username,
+        qualified=True
+    )
 
     feed = {
         "displayName": "Activities by {user}@{host}".format(
@@ -191,17 +256,17 @@ def feed(request):
 @oauth_required
 def object(request, raw_obj=False):
     """ Lookup for a object type """
-    objectType = request.matchdict["objectType"]
+    object_type = request.matchdict["objectType"]
     uuid = request.matchdict["uuid"]
-    if objectType not in ["image"]:
-        error = "Unknown type: {0}".format(objectType)
+    if object_type not in ["image"]:
+        error = "Unknown type: {0}".format(object_type)
         # not sure why this is 404, maybe ask evan. Maybe 400?
         return json_response({"error": error}, status=404)
 
     media = MediaEntry.query.filter_by(slug=uuid).first()
     if media is None:
         # no media found with that uuid
-        error = "Can't find a {0} with ID = {1}".format(objectType, uuid)
+        error = "Can't find a {0} with ID = {1}".format(object_type, uuid)
         return json_response({"error": error}, status=404)
 
     if raw_obj:
@@ -217,14 +282,16 @@ def object_comments(request):
     if isinstance(response, MediaEntry):
         comments = response.serialize(request)
         comments = comments.get("replies", {
-                "totalItems": 0,
-                "items": [],
-                "url": request.urlgen(
-                    "mediagoblin.federation.object.comments",
-                    objectType=media.objectType,
-                    uuid=media.slug,
-                    qualified=True)
-                })
+            "totalItems": 0,
+            "items": [],
+            "url": request.urlgen(
+                "mediagoblin.federation.object.comments",
+                objectType=media.objectType,
+                uuid=media.slug,
+                qualified=True
+            )
+        })
+
         comments["displayName"] = "Replies to {0}".format(comments["url"])
         comments["links"] = {
             "first": comments["url"],
index d9defa4b9da56e3ed0ae33b143d1ead6463cc4e7..8a60392c4739117682297ffbf36802c5a4e3b663 100644 (file)
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from oauthlib.common import Request
-from oauthlib.oauth1 import RequestValidator 
+from oauthlib.oauth1 import RequestValidator
 
 from mediagoblin.db.models import NonceTimestamp, Client, RequestToken, AccessToken
 
-
-
 class GMGRequestValidator(RequestValidator):
 
     enforce_ssl = False
@@ -63,14 +61,14 @@ class GMGRequestValidator(RequestValidator):
         """ Currently a stub - called when making AccessTokens """
         return list()
 
-    def validate_timestamp_and_nonce(self, client_key, timestamp, 
-                                     nonce, request, request_token=None, 
+    def validate_timestamp_and_nonce(self, client_key, timestamp,
+                                     nonce, request, request_token=None,
                                      access_token=None):
         nc = NonceTimestamp.query.filter_by(timestamp=timestamp, nonce=nonce)
         nc = nc.first()
         if nc is None:
             return True
-        
+
         return False
 
     def validate_client_key(self, client_key, request):
@@ -78,7 +76,7 @@ class GMGRequestValidator(RequestValidator):
         client = Client.query.filter_by(id=client_key).first()
         if client is None:
             return False
-        
+
         return True
 
     def validate_access_token(self, client_key, token, request):
@@ -119,9 +117,9 @@ class GMGRequest(Request):
     """
 
     def __init__(self, request, *args, **kwargs):
-        """ 
+        """
             :param request: werkzeug request object
-            
+
             any extra params are passed to oauthlib.common.Request object
         """
         kwargs["uri"] = kwargs.get("uri", request.url)