EzDevInfo.com

appengine-magic

A library designed to make it easy to use Google App Engine from Clojure

Simple example of Sandbar or Ring sessions in Google App Engine

I'm trying to work out how to get sessions and flash working in Google App Engine. Could someone provide a clear example using either Ring or Sandbar? I think I have sandbar working, specifically it doesn't tell me that Var sandbar.stateful-session/sandbar-flash is unbound and when I dump the handler I get :flash and :session though I'm not certain if that is a sandbar session or a ring one. For completeness I will mention that I am using the latest versions of appengine-magic, ring, hiccup and sandbar. There do not appear to be any incompatibilities or issues.

So a clear example preferably with use of flash-put!, flash-get, session-put! and session-get.


Source: (StackOverflow)

Using macros in Clojure

I'm specifically trying to generate the boilerplate for crud functions to work with the Google App Engine datastore using appengine-magic in Clojure. I'm having difficulty working out how to generate values from a model that I've reproduced below.

(def *model* {:users [{:name "Adam"
                       :email "adam@gmail.com"
                       :registered-on "07-05-2011"}
                      {:name "Greg"
                       :email "gregory@gmail.com"
                       :registered-on "11-05-2011"}]
              :post [{:title "A"
                      :authour "Adam"}
                     {:title "B"
                      :author "Greg"}]})

I'm fairly new to appengine-magic, but it provides a defentity which allows you to define entities that you can put into the datastore and save! which allows you to save predefined entities into the datastore.

These take the form of:

(ds/defentity Post [title author])
(ds/save! (Post. title author))

Now just to start with I've defined:

(defn list-entities [model]
  "Takes a representation of the model and lists the entities in preparation for generating defentities"
  (interleave (vec (map first (partition 1 (map (comp symbol capitalize #(str % ".") name) (keys model)))))
    (map vec (map keys (map first (vals model))))))

Calling it with:

(list-entities *model*)

Outputs:

(Users. [:name :email :registered-on] Post. [:title :author])

Now I am having difficulty defining gen-entities which will take the output above and repeatedly call ds/defentities defining as many entities as my model requires.

(defmacro gen-entities [entity fields]
  `(ds/defentity 'entity 'fields))

Additionally I am in no way certain that this is a reasonable way to go about solving this problem. I'm still very new to macros and probably making several mistakes. Any help/clarity would be appreciated.

NOTE:

That model I've realised is badly designed, the one below is a lot better:

(def *model* {:users [:name :email :registered-on]
              :post [:title :author]})

However it is more complex in terms of writing a macro so I will leave it as is.


Source: (StackOverflow)

Advertisements

"Help Arthur find his restricted class" or "how can i make google app engine happy"

somewhere in here I'm using java.rmi.server.UID which is upsetting GAE. After :only'ing my dependencies to the bone I'm at an impasse.

(ns helloworld.core
  (:use ;[hiccup.core]
        [hiccup.page-helpers :only (html5 include-css)]
        [clojure.contrib.string :only (split)]
        [compojure.core :only (defroutes GET)]
        [hiccup.middleware :only (wrap-base-url)])
  (:require [appengine-magic.core :as ae]
            [compojure.route :as route
              :only (resources not-found) ]
            [compojure.handler :as handler :only (site)])
  (:gen-class :extends javax.servlet.http.HttpServlet))

 (defn index-page
  ([name]
     (html5
      [:head
       [:title (str "Hello " name)]
       (include-css "/css/style.css")]
      [:body
       [:h1 (str "Hello " name)]]))
  ([] (index-page "World")))

(def match-opperator
  { "add"      +
    "subtract" -
    "multiply" *
    "divide"   /})

(defroutes hello-routes
  (GET "/:f/*" [f & x]
       (index-page (apply (match-opperator f)
                          (map #(Integer/parseInt %)
                               (split #" " (:* x))))))
  (GET "/" [] (index-page))
  (route/resources "/")
  (route/not-found "Page not found"))

(def app
     (-> (handler/site hello-routes)
         (wrap-base-url)))

(ae/def-appengine-app helloworld-app #'app)

I can load it up in jetty and it works fine, after loading it into the dev-appserver i get this:

HTTP ERROR 500

Problem accessing /multiply/1%202%204%208. Reason:

    java.rmi.server.UID is a restricted class. Please see the Google  App Engine developer's guide for more details.

Caused by:

java.lang.NoClassDefFoundError: java.rmi.server.UID is a restricted class. Please see the Google  App Engine developer's guide for more details.
    at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:51)
    at org.apache.commons.fileupload.disk.DiskFileItem.(DiskFileItem.java:103)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:186)
    at ring.middleware.multipart_params$loading__4414__auto__.invoke(multipart_params.clj:1)
    at ring.middleware.multipart_params__init.load(Unknown Source)
    at ring.middleware.multipart_params__init.(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at clojure.lang.RT.loadClassForName(RT.java:1578)
    at clojure.lang.RT.load(RT.java:399)
    at clojure.lang.RT.load(RT.java:381)
    at clojure.core$load$fn__4519.invoke(core.clj:4915)

ps: here is my project.clj incase this helps:

(defproject helloworld "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.2.1"]
                 [org.clojure/clojure-contrib "1.2.0"]
                 [compojure "0.6.2"]
                 [hiccup "0.3.4"]]

  :dev-dependencies [[appengine-magic "0.4.1"]
                     [swank-clojure "1.2.1"]])

Source: (StackOverflow)

lein appengine-prepare fails

I'm trying get Clojure/Compojure/appengine-magic to work by following the example at https://github.com/gcv/appengine-magic

But when I run lein appengine-prepare I get:

Exception in thread "main" C:\Users\henrik\IdeaProjects\simple-example\lib\dev not found. (NO_SOURCE_FILE:0)
        at clojure.lang.Compiler.eval(Compiler.java:5440)
        at clojure.lang.Compiler.eval(Compiler.java:5391)
        at clojure.core$eval.invoke(core.clj:2382)
        at clojure.main$eval_opt.invoke(main.clj:235)
        at clojure.main$initialize.invoke(main.clj:254)
        at clojure.main$script_opt.invoke(main.clj:270)
        at clojure.main$main.doInvoke(main.clj:354)
        at clojure.lang.RestFn.invoke(RestFn.java:457)
        at clojure.lang.Var.invoke(Var.java:377)
        at clojure.lang.AFn.applyToHelper(AFn.java:172)
        at clojure.lang.Var.applyTo(Var.java:482)
        at clojure.main.main(main.java:37)
Caused by: C:\Users\henrik\IdeaProjects\simple-example\lib\dev not found.

Have I missed something?

lein new simple-example

edit project.clj:

(defproject simple-example "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.2.1"] [appengine-magic "0.4.1"]])

lein deps

lein appengine-new

edit core.clj:

(ns simple-example.core
  (:use compojure.core)
  (:require [appengine-magic.core :as ae]))

(defroutes simple-example-app-handler
  (GET "/" req
       {:status 200
        :headers {"Content-Type" "text/plain"}
        :body "Hello, world!"})
  (GET "/hello/:name" [name]
       {:status 200
        :headers {"Content-Type" "text/plain"}
        :body (format "Hello, %s!" name)})
  (ANY "*" _
       {:status 200
        :headers {"Content-Type" "text/plain"}
        :body "not found"}))

(ae/def-appengine-app simple-example-app #'simple-example-app-handler)

lein appengine-prepare


Source: (StackOverflow)

How to save a Text property using Clojure and appengine-magic

The body field of a form may contain long text, so the default String property won't do.

Looking for how to make the datastore use Text (this is not part of the entity definition like I recall from the Python version), I found this in the source of the ackbar blog:

(ns <snip>
  (:import (com.google.appengine.api.datastore
            EntityNotFoundException Text)))
<snip>
(ds/save! (Post. url title (Text. body) ts in-feed? category))

But if I do the same, I get: "java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: com.google.appengine.api.datastore.Text"

(One notable difference is that the ackbar I'm looking at uses appengine-magic 0.3.2.)

I also tried as-text as briefly mentioned on https://github.com/gcv/appengine-magic#readme, but (as-text body) in there leads to the same error message as above.


EDIT: Turned out the problem wasn't actually to get a Text property into the store, but to make sense of it when retrieving it. My Submit handler triggers saving and than a reload of the form page, and I failed to think of that. Sorry for the noise.

The way to get the value out without hiccup is (.getValue body).


Source: (StackOverflow)

How to interact with a locally running datastore service in appengine-magic?

I'm using appengine-magic to set up a web application, more or less as described at http://www.digitalbricklayers.com/2012/03/geotasklist-in-jquery-mobile-and.html. The example works on my local machine, locations and tasks are added to a local datastore etc.

My question is if it is possible to interact with the datastore from within a REPL, e.g. call (ds/save! ...) etc. during interactive development? I ask because when I try I get:

NullPointerException No API environment is registered for this thread.
com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppId (DatastoreApiHelper.java:108)

I'm getting this error no matter if I use an eclipse+counterclockwise based setup or an emacs+slime based setup.

Thanks, Joachim


Source: (StackOverflow)

appengine magic, almost satisfied but getting null pointer on repl

I got webapp (made with appengine-magic and lein) working on dev_appserver.sh but because I need more interactivity and less restarting the server I prefer to use repl. Now problem is, that after I do (require '[appengine-magic.core :as ae]), (use 'myapp.core) and try to serve application (ae/serve myapp) I get this exception:

[Thrown class java.lang.NullPointerException]

Backtrace:
  0: java.io.File.<init>(File.java:360)
  1: sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  2: sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
  3: sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
  4: java.lang.reflect.Constructor.newInstance(Constructor.java:513)
  5: clojure.lang.Reflector.invokeConstructor(Reflector.java:160)
  6: appengine_magic.core$start.doInvoke(core_local.clj:85)
  7: clojure.lang.RestFn.invoke(RestFn.java:439)
  8: appengine_magic.core$serve.doInvoke(core_local.clj:139)
  9: clojure.lang.RestFn.invoke(RestFn.java:410)
 10: user$eval2264.invoke(NO_SOURCE_FILE:1)
 11: clojure.lang.Compiler.eval(Compiler.java:5424)
 12: clojure.lang.Compiler.eval(Compiler.java:5391)
 13: clojure.core$eval.invoke(core.clj:2382)
 14: swank.commands.basic$eval_region.invoke(basic.clj:47)
 15: swank.commands.basic$eval_region.invoke(basic.clj:37)
 16: swank.commands.basic$eval807$listener_eval__808.invoke(basic.clj:71)
 17: clojure.lang.Var.invoke(Var.java:365)
 18: user$eval2262.invoke(NO_SOURCE_FILE)
 19: clojure.lang.Compiler.eval(Compiler.java:5424)
 20: clojure.lang.Compiler.eval(Compiler.java:5391)
 21: clojure.core$eval.invoke(core.clj:2382)
 22: swank.core$eval_in_emacs_package.invoke(core.clj:92)
 23: swank.core$eval_for_emacs.invoke(core.clj:239)
 24: clojure.lang.Var.invoke(Var.java:373)
 25: clojure.lang.AFn.applyToHelper(AFn.java:167)
 26: clojure.lang.Var.applyTo(Var.java:482)
 27: clojure.core$apply.invoke(core.clj:540)
 28: swank.core$eval_from_control.invoke(core.clj:99)
 29: swank.core$eval_loop.invoke(core.clj:104)
 30: swank.core$spawn_repl_thread$fn__493$fn__494.invoke(core.clj:309)
 31: clojure.lang.AFn.applyToHelper(AFn.java:159)
 32: clojure.lang.AFn.applyTo(AFn.java:151)
 33: clojure.core$apply.invoke(core.clj:540)
 34: swank.core$spawn_repl_thread$fn__493.doInvoke(core.clj:306)
 35: clojure.lang.RestFn.invoke(RestFn.java:397)
 36: clojure.lang.AFn.run(AFn.java:24)
 37: java.lang.Thread.run(Thread.java:680)

I have also tried (in-ns 'myapp.core) but same effect. When I paste web app handler straight on repl and serve then it works, but not from my file.

calling myapp or myapp-handler clearly gives the "object" so I should really be on right namespace...

project.clj

(defproject myapp "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [
        [org.clojure/clojure "1.2.1"]
        [compojure "0.6.2"]
        ]
  :dev-dependencies [
            [appengine-magic "0.4.1"]
            [ring/ring-devel "0.3.7"]
            ])

core.clj is as just simple:

(ns myapp.core
    (:use compojure.core)
    (:require [appengine-magic.core :as ae]))

(defroutes myapp-handler
    (GET "/" req
       {:status 200
        :headers {"Content-Type" "text/plain"}
        :body "Hello, world!!!"}))

(ae/def-appengine-app myapp #'myapp-handler)

Source: (StackOverflow)

clojure+appengine-magic java.lang.NoClassDefFoundError: clojure/lang/IFn

I tried to make example to use google appengine with appengine-magic.

I think I did as the usage

but I got the following problem.

Problem accessing /parents. Reason:

    clojure/lang/IFn
Caused by:

java.lang.NoClassDefFoundError: clojure/lang/IFn
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2493)
    at java.lang.Class.getConstructor0(Class.java:2803)
    at java.lang.Class.newInstance(Class.java:345)

this is my source project


Source: (StackOverflow)

Issues with getting both POST and GET http parameters in appengine-magic 0.4.3/Compojure 0.6.4

I'm having some serious issues with capturing POST and GET parameters with the latest appengine-magic/compojure versions. The parameters always come up as blank, even though the request object clearly has the right stuff in it.

I've seen some stuff around the interwebs about a change in the Compojure protocol where you have to manually put in the wrappers. I've tried this (using the handler/api wrapper to avoid the stuff in handler/site wrapper that breaks GAE) but it still doesn't work.

What am I doing wrong here?

My project.clj file:

(defproject pitch-filter "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.2.0"]
         [org.clojure/clojure-contrib "1.2.0"]
         [compojure "0.6.4"]
         [hiccup "0.3.6"]
         [jtidy "4aug2000r7-dev"]
         [commons-lang "2.5"]]
  :dev-dependencies [[appengine-magic "0.4.2"]
             [clj-http "0.1.1"]])

My core.clj file:

(ns pitch-filter.core
  (:use compojure.core
    [appengine-magic.multipart-params :only [wrap-multipart-params]]
    [hiccup.middleware :only (wrap-base-url)])
  (:require [pitch-filter.fetch :as fetch]
        [compojure.route :as route]
        [compojure.handler :as handler]
        [appengine-magic.core :as ae]
        [appengine-magic.services.url-fetch :as url]


(defroutes pitch-filter-app-routes
  (GET "/" [] "Main Page")
  (GET "/form" []
    (str "<form method='post' action='/post'>"
         "<input type='text' name='test'>"
         "<input type='submit'>"
         "</form>"))
  (POST "/post" {params :params}
    (pr-str params))
  (route/not-found "Page not found"))


(def pitch-filter-app-handler
     (-> pitch-filter-app-routes
     (handler/api)
     (wrap-base-url)
     ))

(ae/def-appengine-app pitch-filter-app #'pitch-filter-app-handler)

Source: (StackOverflow)