← Back to team overview

ladon-dev-team team mailing list archive

Re: REST implementation

 

Sure, I think I'm an adequate :) I also just would like to find the best
solution. I told - it's just a proposal, and I made some thoughts on it,
just share them with you. Finally, our goal the same - to provide the best
solution to the end-user. BTW, I just don't know how to provide service
description - it's something out of the existing standards. That's why I
was asking in the past  - what to do with that?

Mike

2012/10/23 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>

> Hi Mike
>
> I hope you understand that I'm not rejecting your proposal at all :-) just
> throwing balls in the air and alternative suggestions so we can reach the
> best solution. Tonight I am gonna review your branch in more detail and
> give you some feedback.
>
> Earlier you mentioned that all you really need to describe the restful
> service is a list of objects. I don't entirely agree with this unless that
> list also contains object info ie. attribute names and types.
>
>
> / Jakob
>
> 2012/10/23 Mykhailo Stadnyk <mikhus@xxxxxxxxx>
>
>> Initially I was supposed to implement in some kind of way, but just using
>> the class-level decorator. But! It is too strict and not as flexible as
>> could be.
>> I told already taht I imagine that exposing RESTful methods might be a
>> bit more flexible.  Let's imagine that I already have some SOAP service
>> which is easily could map to REST by exposing the methods (assuming that
>> SOAP service is "almost RESTful", but all I need is to expose to HTTP GET
>> not a single method but several). You can look at, for example, JAX-WS -
>> the REST implementation is something like in my proposal. You put TOO
>> strict constraints for the REST service, mine is more flexible. I propose
>> to developer to decide what does he want to do with his service (he might
>> want to have 2 POST, 5 GET, 1 PUT and no DELETE HTTP methods exposed for
>> concrete service object). This mapping could be easily done by matching the
>> arguments passed through an HTTP, so the rule is a following:
>>  1. If you have several methods exposed to the same type of HTTP request,
>> which method to call is determined by matching the bypassed HTTP params and
>> the service method arguments
>>  2. REST is not RPC, so you can not tell which method to call by name,
>> but we can call different methods relying on their signatures
>>
>> 1,2 - the same but with different words.
>>
>> Regards,
>> Mike
>>
>> 2012/10/23 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>>
>>> Let's try to define the end-user result, and then discuss the
>>> implementation afterwards.
>>>
>>> In the following I have defined a very simple type as a case we can
>>> collaborate through.
>>>
>>> Maybe we have an object called Client that needs to be RESTful. I think
>>> the nicest thing to do would be to SubClass LadonType (ie.
>>> RESTfulLadonType) which has some virtual methods:
>>>
>>> class Client(RESTfulLadonType):
>>>
>>>   uid = PORTABLE_STRING
>>>   name = PORTABLE_STRING
>>>   account = PORTABLE_STRING
>>>   credit = bool
>>>
>>>   def get(self,id):
>>>     pass
>>>
>>>   def put(self,id):
>>>     pass
>>>
>>>   def delete(self,id):
>>>     pass
>>>
>>> Ladon sees right away that some og the objects used in the Service class
>>> are RESTful and adds restful to the list of protocols.
>>> Your turn!
>>>
>>> / Jakob
>>>
>>>
>>>
>>> 2012/10/23 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>>>
>>>> I knew this already :-) And that's not nessesarilly a bad thing,
>>>> depending on what you are developing. I just think we need to think through
>>>> how to implement it in Ladon. Since you have enjoyed using Ladon until now,
>>>> you probably already know that I am a hugh fan of end-user simplicity.
>>>>
>>>> And since REST is strictly object-oriented, I really think we should be
>>>> looking at decorating the LadonType instead of methods. I haven't thought
>>>> it all the way through yet, but I'm almost sure that would be the place to
>>>> do it.
>>>>
>>>>
>>>> / Jakob
>>>>
>>>>
>>>> 2012/10/23 Mykhailo Stadnyk <mikhus@xxxxxxxxx>
>>>>
>>>>> Exacly! REST is a constraint to objects by design! You've caught it.
>>>>> But it's good principal for data-oriented services with no overhead by any
>>>>> top-level protocol. It's a principal of building RESTful services. And will
>>>>> be good if Ladon will support it
>>>>>
>>>>> 2012/10/23 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>>>>>
>>>>>>  But, I think I know what you mean. It's the fact that it utilizes
>>>>>> all HTTP methods that makes you say that REST is in the HTTP protocol. I
>>>>>> just don't nessesarily find that this is very revolutionary. It's more of a
>>>>>> constraint, cause you are limited to objects by design.
>>>>>>
>>>>>> / Jakob
>>>>>>
>>>>>>
>>>>>> 2012/10/23 Mykhailo Stadnyk <mikhus@xxxxxxxxx>
>>>>>>
>>>>>>> For REST HTTP is not underlying level but the protocol itself. In
>>>>>>> terms of REST design of service is known, so all you need is just to
>>>>>>> describe a list of objects. And then for each object there is 4 operations
>>>>>>> you are able to perform Create (HTTP PUT), Read (HTTP GET), Update (HTTP
>>>>>>> POST) and Delete (HTTP DELETE). That's why in terms of REST you do not need
>>>>>>> the description. You have only URLs each representing the object you can do
>>>>>>> direct HTTP requests and you have no overhead of having some top-level
>>>>>>> protocol, etc. That's why I said that REST is HTTP, because there is
>>>>>>> nothing on top of HTTP in REST. And there is nothing to describe, only the
>>>>>>> object URLs.
>>>>>>>
>>>>>>> It means that RESTful service architecture is not as flexible as
>>>>>>> SOAP, so if you, as developer decided to create RESTful service it means
>>>>>>> that you already chosen the service architecture. It also means that not
>>>>>>> every SOAP service can be RESTful, but RESTful service could be delivered
>>>>>>> with SOAP.
>>>>>>> So you, as developer MUST decide first if you are building a RESTful
>>>>>>> service, if so - go ahead, make it and Ladon give you benefit to deliver
>>>>>>> your RESTful service throug varius different supported protocols.
>>>>>>>
>>>>>>> Again. You CAN deliver RESTful service throug
>>>>>>> SOAP/XML-RPC/JSON-WSP/etc. But you CAN NOT deliver abstract
>>>>>>> SOAP/XML-RPC/JSON-WSP service through REST if it wasn't designed as RESTful
>>>>>>>
>>>>>>> In my implementation I've tried to make everything with maximum
>>>>>>> flexibility, so each RESTFul service could have more than 4 CRUD methods,
>>>>>>> for each HTTP request method you can have as many service methods as you
>>>>>>> need if the service methods have different signatures (arguments)
>>>>>>>
>>>>>>> like
>>>>>>>
>>>>>>> class Service:
>>>>>>>     @restfulize(method="GET")
>>>>>>>     def get_one_record( r_id):
>>>>>>>          pass
>>>>>>>     @restfulize(method="GET")
>>>>>>>     def get_last_record( r_time):
>>>>>>>          pass
>>>>>>>     @restfulize(method="GET")
>>>>>>>     def get_all_records():
>>>>>>>          pass
>>>>>>>     @restfulize(method="GET")
>>>>>>>     def get_filtered_records( filters):
>>>>>>>          pass
>>>>>>>
>>>>>>> As you see in this example 4 service methods are bind to HTTP GET
>>>>>>> method. Depending of parameters bypassed through HTTP I try to determine
>>>>>>> which method to call, but from terms of protocol you always do
>>>>>>>
>>>>>>> GET
>>>>>>> /Service/rest?filters['name']=*bla&filters['another_key']=somevalue HTTP/1.1
>>>>>>> Host: yourservice.com
>>>>>>> ...
>>>>>>>
>>>>>>> The same for other HTTP methods. You can have 2 different methods
>>>>>>> for POST, for example for User service example you may have split User data
>>>>>>> update and user password update, etc..
>>>>>>>
>>>>>>> Or maybe your service may not provide some methods. Like you create
>>>>>>> the public read-only service, so you don't provide PUT/POST/DELETE
>>>>>>>
>>>>>>> P.S. REST does not provide the way do bypass which service method to
>>>>>>> call by name. REST is not RPC. You have only the Resource, it's URL and 4
>>>>>>> operations. It is REST.
>>>>>>>
>>>>>>> Best regards,
>>>>>>> Mike
>>>>>>>
>>>>>>>
>>>>>>> 2012/10/23 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>>>>>>>
>>>>>>>> Everything in Ladon is HTTP :-)
>>>>>>>>
>>>>>>>> But HTTP is just the underlying protocol, and under that is a
>>>>>>>> transport protocol etc.
>>>>>>>>
>>>>>>>> When I am talking about protocol in Ladon I mean service protocols
>>>>>>>> like soap, json-wsp and soon json-rpc which are also protocols. I would put
>>>>>>>> REST at this level aswell.
>>>>>>>>
>>>>>>>> I haven't really used REST before, but from what I can see it is
>>>>>>>> nothing more than another service protocol which utilizes the HTTP standard
>>>>>>>> a bit more, like using PUT,POST,GET,DELETE methods. Also it looks like
>>>>>>>> there is not so much constraint on how parameters are passed so they can be
>>>>>>>> JSON or XML or query-string.
>>>>>>>>
>>>>>>>> I don't like that there is no service description format for REST
>>>>>>>> services. That is kind of a key feature in Ladon, that all supported
>>>>>>>> protocols should be able to describe themselves.
>>>>>>>>
>>>>>>>>
>>>>>>>> / Jakob
>>>>>>>>
>>>>>>>> 2012/10/22 Mykhailo Stadnyk <mikhus@xxxxxxxxx>
>>>>>>>>
>>>>>>>>> What do you mean?
>>>>>>>>>
>>>>>>>>> Actually REST is HTTP in terms of protocol, so what do I need to
>>>>>>>>> implement? Maybe you can explain me more detailed your thought.
>>>>>>>>>
>>>>>>>>> Best regards,
>>>>>>>>> Mike
>>>>>>>>>
>>>>>>>>> 2012/10/22 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>>>>>>>>>
>>>>>>>>>> My first question about your RESTful implementation is, why are
>>>>>>>>>> you not implementing it as a protocol?
>>>>>>>>>>
>>>>>>>>>> / Jakob
>>>>>>>>>>
>>>>>>>>>> 2012/10/22 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>>>>>>>>>>
>>>>>>>>>>> Just a remark about the package name tracepyd. That might be an
>>>>>>>>>>> unfortunate package name, cause on that odd platform called Windows
>>>>>>>>>>> pyd-files are binary python modules. Just a remark :-)
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> 2012/10/22 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>>>>>>>>>>>
>>>>>>>>>>>> Hi Mike.
>>>>>>>>>>>>
>>>>>>>>>>>> Let's talk about tracepyd first, does it solve this bug:
>>>>>>>>>>>>
>>>>>>>>>>>> https://bugs.launchpad.net/ladon/+bug/877727
>>>>>>>>>>>>
>>>>>>>>>>>> rpclib has a terribly ugly solution for this, as you can see in
>>>>>>>>>>>> the bug, and we want to be better than rpclib :-)
>>>>>>>>>>>>
>>>>>>>>>>>> / Jakob
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> 2012/10/22 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>>>>>>>>>>>>
>>>>>>>>>>>>> Hi Mike
>>>>>>>>>>>>>
>>>>>>>>>>>>> Looking into this now, you will have my reply today :-)
>>>>>>>>>>>>>
>>>>>>>>>>>>> / Jakob
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/22 Mykhailo Stadnyk <mikhus@xxxxxxxxx>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Currently it's an experimental feature which is not ready to
>>>>>>>>>>>>>> be integrated. I didn't test it at all (keep working on it).
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> So here is my personal road-map for this feature:
>>>>>>>>>>>>>>   1. Resolve problem with decorators dependencies (something
>>>>>>>>>>>>>> I described in previous message)
>>>>>>>>>>>>>>   2. Write tests and test the functionality
>>>>>>>>>>>>>>   3. I've not checked how does it deal with requests
>>>>>>>>>>>>>> containing multipart boundaries and binary data
>>>>>>>>>>>>>>   4. Not sure what to do with service description (currently
>>>>>>>>>>>>>> I've just removed, but have an idea we can use it to describe service any
>>>>>>>>>>>>>> way, even as long as REST does not specify this)
>>>>>>>>>>>>>>   5. Write documentation/examples
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> But I'm stuck on issue #1. I want to know:
>>>>>>>>>>>>>>  * do you agree to add dependency in Ladon to tracepyd module
>>>>>>>>>>>>>> or not?
>>>>>>>>>>>>>>  * If not - do you agree to include tracepyd's implementation
>>>>>>>>>>>>>> into Ladon (not as dependency, but to place it somewhere in tools)?
>>>>>>>>>>>>>>  * If not - do you agree to modify @ladonize decorator
>>>>>>>>>>>>>> functionality to add extra-params for REST (for me its ugly).
>>>>>>>>>>>>>>  * If not - which ideas do you have then? :)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I'd like to suggest to add dependency to tracepyd. Currently
>>>>>>>>>>>>>> I have a version locally which works fine, so I can publish this solution
>>>>>>>>>>>>>> to my branch to let you see.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thank you in advance for your time and advice,
>>>>>>>>>>>>>> Mike
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2012/10/22 Jakob Simon-Gaarde <jakobsg@xxxxxxxxx>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Interesting :-)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I'll look at it later - we must make sure that it doesn't
>>>>>>>>>>>>>>> break anything.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2012/10/22 Mykhailo Stadnyk <mikhus@xxxxxxxxx>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi Jacob.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> As I told I'm trying to implement RESTful services support
>>>>>>>>>>>>>>>> by Ladon. The basic functionality is implemented - you can check my branch:
>>>>>>>>>>>>>>>> lp:~mikhus/ladon/rest<https://code.launchpad.net/~mikhus/ladon/rest> to
>>>>>>>>>>>>>>>> see how does it work. Here is an example of RESTful service you may run to
>>>>>>>>>>>>>>>> see:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> from ladon.ladonizer import ladonize, restfulize
>>>>>>>>>>>>>>>> from ladon.compat import PORTABLE_STRING
>>>>>>>>>>>>>>>> from ladon.types.ladontype import LadonType
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> class User(LadonType):
>>>>>>>>>>>>>>>>  name = PORTABLE_STRING
>>>>>>>>>>>>>>>> email = PORTABLE_STRING
>>>>>>>>>>>>>>>> passwd = PORTABLE_STRING
>>>>>>>>>>>>>>>>  def __init__():
>>>>>>>>>>>>>>>>  self.name = ""
>>>>>>>>>>>>>>>>  self.email = ""
>>>>>>>>>>>>>>>>  self.passwd = ""
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> class UserService( object) :
>>>>>>>>>>>>>>>>  @restfulize(method="PUT")
>>>>>>>>>>>>>>>>  @ladonize(str, str, str, rtype=User)
>>>>>>>>>>>>>>>> def newUser( self, u_name, u_email, u_passwd) :
>>>>>>>>>>>>>>>>  user = User() # where User is LadonType object
>>>>>>>>>>>>>>>> user.name   = u_name
>>>>>>>>>>>>>>>>  user.email  = u_email
>>>>>>>>>>>>>>>> user.passwd = u_passwd
>>>>>>>>>>>>>>>> return user
>>>>>>>>>>>>>>>>  @restfulize(method="GET")
>>>>>>>>>>>>>>>> @ladonize(int, rtype=[User])
>>>>>>>>>>>>>>>>  def getUser(self, u_id) :
>>>>>>>>>>>>>>>> return User()
>>>>>>>>>>>>>>>>  @restfulize(method="GET")
>>>>>>>>>>>>>>>> @ladonize(int, rtype=[User])
>>>>>>>>>>>>>>>> def getUsers(self) :
>>>>>>>>>>>>>>>>  return [User(), User(), User()]
>>>>>>>>>>>>>>>>  @restfulize(method="POST")
>>>>>>>>>>>>>>>>  @ladonize(int, str, str, str, rtype=User)
>>>>>>>>>>>>>>>> def updUser( self, u_id, u_name, u_email, u_passwd):
>>>>>>>>>>>>>>>>  user = User()
>>>>>>>>>>>>>>>> user.name   = u_name
>>>>>>>>>>>>>>>> user.email  = u_email
>>>>>>>>>>>>>>>>  user.passwd = u_passwd
>>>>>>>>>>>>>>>> return user
>>>>>>>>>>>>>>>>  @restfulize(method="DELETE")
>>>>>>>>>>>>>>>> @ladonize(int, rtype=bool)
>>>>>>>>>>>>>>>> def delUser( self, u_id) :
>>>>>>>>>>>>>>>>  return True
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> By the way, there is at least one issue I don't know how to
>>>>>>>>>>>>>>>> solve better, so I want your advice.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> As you see I've implemented specific decorator to mark
>>>>>>>>>>>>>>>> service methods as RESTful. It's @restfulize decorator. The problem that it
>>>>>>>>>>>>>>>> is implemented now as:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> def restfulize( *dargs, **dkwargs):
>>>>>>>>>>>>>>>>  def decorator(fn):
>>>>>>>>>>>>>>>> * minfo = fn._ladon_method_info*
>>>>>>>>>>>>>>>> if 'method' in dkwargs:
>>>>>>>>>>>>>>>>  if not minfo.restfulize( **dkwargs):
>>>>>>>>>>>>>>>> raise RestfulMethodConfigMismatch( fn.func_name)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> return fn # returns ladonized method
>>>>>>>>>>>>>>>> return decorator
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The problem is highlighted with bold. Will be good to make
>>>>>>>>>>>>>>>> this decorator independent of what @ladonize defined in it's private props.
>>>>>>>>>>>>>>>> But, as far as "fn" here is a reference to ladon's "injector" function I
>>>>>>>>>>>>>>>> have no way to determine correctly which real method in which class is
>>>>>>>>>>>>>>>> decorated. It means that in such case I have no way to extract
>>>>>>>>>>>>>>>> LadonMethodInfo associated to "fn" in other way but implemented for the
>>>>>>>>>>>>>>>> moment.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The real problem is when I want to override @ladonize
>>>>>>>>>>>>>>>> decorator. In this case @resftulize becomes nonoperational because I loose
>>>>>>>>>>>>>>>> reference to "_ladon_method_info" and means that I should take care to
>>>>>>>>>>>>>>>> bypass all the existing private properties in 3-d party override
>>>>>>>>>>>>>>>> implementation, which is not good at all. So I want to have @restfulize and
>>>>>>>>>>>>>>>> @ladonize implemented without hard dependency between them.
>>>>>>>>>>>>>>>> Via global_service_collection() it's possible to do but you
>>>>>>>>>>>>>>>> need to determine real method function in some way.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> So I see the following ways to fix it:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 1. Via decorator registry (Here we solved such kind of
>>>>>>>>>>>>>>>> problem by creating DecoratorRegistry (I've published it as
>>>>>>>>>>>>>>>> http://pypi.python.org/pypi/tracepyd))
>>>>>>>>>>>>>>>> 2. By adding REST functionality to @ladonize decorator
>>>>>>>>>>>>>>>> itself, to have something like:
>>>>>>>>>>>>>>>>     @ladonize(PORTABLE_STRING, rtype=[PORTABLE_STRING], *rest={
>>>>>>>>>>>>>>>> "method" : "GET", "produces": "XML" }*)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Maybe you can point me to some other ideas you know how to
>>>>>>>>>>>>>>>> resolve such kind of problem.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Best regards,
>>>>>>>>>>>>>>>> Mike
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Med venlig hilsen / Best regards
>>>>>>>>>>>>>>> Jakob Simon-Gaarde
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Med venlig hilsen / Best regards
>>>>>>>>>>>>> Jakob Simon-Gaarde
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Med venlig hilsen / Best regards
>>>>>>>>>>>> Jakob Simon-Gaarde
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Med venlig hilsen / Best regards
>>>>>>>>>>> Jakob Simon-Gaarde
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Med venlig hilsen / Best regards
>>>>>>>>>> Jakob Simon-Gaarde
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Med venlig hilsen / Best regards
>>>>>>>> Jakob Simon-Gaarde
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Med venlig hilsen / Best regards
>>>>>> Jakob Simon-Gaarde
>>>>>>
>>>>>> --
>>>>>> Mailing list: https://launchpad.net/~ladon-dev-team
>>>>>> Post to     : ladon-dev-team@xxxxxxxxxxxxxxxxxxx
>>>>>> Unsubscribe : https://launchpad.net/~ladon-dev-team
>>>>>> More help   : https://help.launchpad.net/ListHelp
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Med venlig hilsen / Best regards
>>>> Jakob Simon-Gaarde
>>>>
>>>
>>>
>>>
>>> --
>>> Med venlig hilsen / Best regards
>>> Jakob Simon-Gaarde
>>>
>>> --
>>> Mailing list: https://launchpad.net/~ladon-dev-team
>>> Post to     : ladon-dev-team@xxxxxxxxxxxxxxxxxxx
>>> Unsubscribe : https://launchpad.net/~ladon-dev-team
>>> More help   : https://help.launchpad.net/ListHelp
>>>
>>>
>>
>
>
> --
> Med venlig hilsen / Best regards
> Jakob Simon-Gaarde
>
> --
> Mailing list: https://launchpad.net/~ladon-dev-team
> Post to     : ladon-dev-team@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~ladon-dev-team
> More help   : https://help.launchpad.net/ListHelp
>
>

Follow ups

References