AkShell Wiki

21 views
Skip to first unread message

pranakhan

unread,
May 18, 2011, 7:46:38 PM5/18/11
to akshell
I've just started to REALLY explore the possibilities with AkShell and
I'm definately more and more impressed.

One thing I've noticed is that there is no common location for AkShell
users to share information with eachother. Where can we find a list of
public AkShell libraries and apps? Learn more about using the Eval
interfaces, or even provide user generated documentation.

Right now, you have the feedback forms, the idea forums, this group
and Facebook group, but its all over the place.

Perhaps we could develop an AkShell based Wiki and self-host the
AkShell Wiki on it? I'd be willing to play around with building that,
it would also make a great AkShell demo/tutorial.

Comments?

Thanks!

Andy (Pranakhan)

Oleg Podsechin

unread,
May 19, 2011, 1:41:47 AM5/19/11
to aks...@googlegroups.com
Glad you like it!

Currently the only public place to discuss Akshell is this mailing
list, so I agree that a wiki would be useful. It would be terrific if
you could put something together.

If you don't want to start from scratch, there is a version of a basic
wiki for Akshell 0.2 (previous version) that I wrote the source to
which you can find here:

http://old.akshell.com/apps/wikis/code/

It depends on the following two libraries which you may need to port to 0.3:

http://old.akshell.com/apps/markdown/code/ - no dependencies, should
be easy to move across
http://old.akshell.com/apps/store/code/ - used to provide a simple
storage mechanism, depends on Proxy, the location of which has changed
but the functionality is much the same, it's also available at
https://github.com/akshell/kv

Also, glad to see you managed to resolve the issue you were having
with static files. If you want to look at its internals, the MVC
framework is open source and you can find it here:
https://github.com/akshell/ak/blob/master/rest.js

The MVC framework runs on top of the standard CommonJS JSGI interface,
so the most basic Akshell app is actually:

require('ak'); // this won't be needed in the near future
exports.app = function(env) {
return {
status: 200,
headers: {},
body: ["Hello World!"]
};
}

Oleg

> --
> You received this message because you are subscribed to the Google Groups "akshell" group.
> To post to this group, send email to aks...@googlegroups.com.
> To unsubscribe from this group, send email to akshell+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/akshell?hl=en.
>
>

pranakhan

unread,
May 20, 2011, 4:59:00 PM5/20/11
to akshell
Thanks Oleg!

I've already started working on the wiki stuff, trying to really do it
the "AkShell Way" as much as possible by following the MVC examples.
I've been using PHPWiki as my architectural model, related to db
layout and such, but processing in Akshell is quite a bit different
than in PHP.

I've already put together the basic mapping and handlers for the most
basic of wiki functionality. I'm trying to build it as a module
library as well. I love the URL mapping scheme you guys have, it was
easy to create handlers for the following URL types:

site.com/wiki
site.com/wiki/SomePage
site.com/wiki/SomePage/version/2
site.com/wiki/SomePage/edit/ (and history, and so forth)

I was sweating porting markdown stuff over but since you already did
that I'll DEFINATELY reuse that!

I realized that a wiki has several important common web-app elements
that I am thinking of making separate module libraries: session
management, user authentication/authorization/prefs

Also, since the file system is read only, I have been putting together
an interesting method of allowing uploads of arbitrary files like
images, by creating another module library that stores the file data
in the DB in Binary format (with size/quota limitations of course).
Looking through the docs, I really don't see any limitations in
AkShell that would prevent some lower level handling of HTTP, in fact,
it looks like you guys designed it with that flexibility. Good stuff!

I'll take a look at the work you did already and try to reuse as much
of that as possible, it will probably also help me understand Akshell
a bit better.

One note: The eval tool... at the moment its a little limited, it
would probably be much more powerful if it has a bit more "shell" like
capability with extensible builtin functions or commands. Looking at
Firebug for inspiration, it would be great to have console output from
running apps, perhaps creating a seperate "console" from "eval"? Right
now the output from eval is also pretty limited, mostly returning
[Object object] when evaluating the value of pretty much anything. Any
suggestions here, am I missing something?

Thanks!

Andy (Pranakhan)

On May 18, 11:41 pm, Oleg Podsechin <o...@akshell.com> wrote:
> Glad you like it!
>
> Currently the only public place to discuss Akshell is this mailing
> list, so I agree that a wiki would be useful. It would be terrific if
> you could put something together.
>
> If you don't want to start from scratch, there is a version of a basic
> wiki for Akshell 0.2 (previous version) that I wrote the source to
> which you can find here:
>
> http://old.akshell.com/apps/wikis/code/
>
> It depends on the following two libraries which you may need to port to 0.3:
>
> http://old.akshell.com/apps/markdown/code/- no dependencies, should
> be easy to move acrosshttp://old.akshell.com/apps/store/code/- used to provide a simple
> storage mechanism, depends on Proxy, the location of which has changed
> but the functionality is much the same, it's also available athttps://github.com/akshell/kv

Oleg Podsechin

unread,
May 21, 2011, 12:21:43 AM5/21/11
to aks...@googlegroups.com
One note: The eval tool... at the moment its a little limited, it
would probably be much more powerful if it has a bit more "shell" like
capability with extensible builtin functions or commands. Looking at
Firebug for inspiration, it would be great to have console output from
running apps, perhaps creating a seperate "console" from "eval"? Right
now the output from eval is also pretty limited, mostly returning
[Object object] when evaluating the value of pretty much anything. Any
suggestions here, am I missing something?

We are looking to add a Firebug like console.log functionality, the output of which you could view separately.

With regards to eval, you can use JSON.stringify(method()) instead of method() to print the contents of the returned objects. By default it just calls the toString() method of the returned object.

Oleg

Oleg Podsechin

unread,
May 21, 2011, 12:24:55 AM5/21/11
to aks...@googlegroups.com
Also, since the file system is read only, I have been putting together
an interesting method of allowing uploads of arbitrary files like
images, by creating another module library that stores the file data
in the DB in Binary format (with size/quota limitations of course).
Looking through the docs, I really don't see any limitations in
AkShell that would prevent some lower level handling of HTTP, in fact,
it looks like you guys designed it with that flexibility. Good stuff!

This is exactly how we envisaged file uploads as working. You may run into issues when it comes to handling multipart POSTs though. We implemented this functionality just recently and it's not documented anywhere, but Anton will be able to share the code with you.

Oleg  

Anton Korenyushkin

unread,
May 23, 2011, 11:09:04 AM5/23/11
to aks...@googlegroups.com
Here is the middleware parsing multipart data:

function parseheader(serve){
function parseURLEncodedData(data) {
  var result = {};
  data.split(/[&;]/).forEach(
    function (part) {
      var nv = part.split('=');
      if (nv.length == 2)
        addProp(result, decodeURIPlus(nv[0]), decodeURIPlus(nv[1]));
    });
  return result;
}
  var f = function(request){

    var split_binary = function(binary, substr){
      var results = [];
      var new_position;
      var prev_position = 0;
      var substr_len = substr.length;
      while(1){
        new_position = binary.indexOf(substr, prev_position);
        if(new_position === -1){
          break;
        }
        results.push([prev_position, new_position-1]);
        prev_position = new_position + substr_len;
      }

      results.push([prev_position, binary.length-1]);
      // return results;
      for (var i in results){
        if(results.hasOwnProperty(i)){
          results[i] = binary.range(results[i][0], results[i][1]+1);
        }
      }
      return results;
    };
    var i;
    var m;
    if(request.method.toLowerCase()==='post' && request.headers['content-type'].toLowerCase().startsWith('multipart/form-data')){
      var ctype = request.headers['content-type'];
      m = ctype.match(/^.*;\s+boundary=(.*)$/);
      if(m){
        var boundary = m[1];
        var content = split_binary(request.data,boundary);
        var parts = [];
        for(i in content){
          if (content.hasOwnProperty(i)){
            var binary_content = content[i];
            var string_content = binary_content.toString();
            var s = string_content.replace(/^[\r\n]+/,'').replace(/[\r\n]+(--)?$/,'');
            if(s === '--'){
              continue;
            }
            var split_pos = binary_content.indexOf("\r\n\r\n");
            if(split_pos === -1){
              err("WTF?");
            }
            var header = binary_content.range(0, split_pos).toString();
            var body = binary_content.range(split_pos + 4);
            if (body.lastIndexOf("\r\n--") === body.length - 4){
              body = body.range(0,body.length - 4);
            }
            parts.push([header, body]);
          }
        }
      }
      var post = {};
      var files = [];
      for(i in parts){
        var part = parts[i];
        var header = part[0];
        var body = part[1];

        m = header.match(/content-disposition:\s*form-data\;\s*name="?([^";]+)"?/i);
        if(!m){ // name not found
          err("Name not found for 'm'");
          continue;
        }
        var field_name = m[1];
        m = header.match(/content-type:\s*([^ \r\n\t]+)/i);
        if(m){
          var content_type = m[1];
          var filename = null;
          m = header.match(/filename="([^"]*)"/);
          if(m){
            filename = m[1];
          }
          files[field_name] = {
            'name': filename,
            'type': content_type.toLowerCase(),
            'file': body
          };
        }else{
          body = body.toString().replace(/\r\n--$/,'');
          post[field_name] = body;
        }
      }
      request.post = post;
      request.files = files;
    }
    return serve(request);
  };
  return f;
};

You can use it like this:

exports.main = defaultServe.decorated(parseheader);

It's rather ad-hoc and lacks tests. We are working on the more polished solution to integrate into the framework.


--
You received this message because you are subscribed to the Google Groups "akshell" group.
To post to this group, send email to aks...@googlegroups.com.
To unsubscribe from this group, send email to akshell+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akshell?hl=en.

pranakhan

unread,
May 24, 2011, 12:42:26 PM5/24/11
to akshell
Thanks for the code snippet, I brought it into a new project which
will act as a stand-alone file store similar to Amazon's S3 service...
For now... Once I finish putting together the basic functionality
maybe you can help me figure out which direction to go with it (module
vs. service, etc).

Thanks!

Andy (Pranakhan)
Reply all
Reply to author
Forward
0 new messages