
#######################################################################
#  This file is part of GNOWSYS: Gnowledge Networking and
#  Organizing System.
#
#  GNOWSYS is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as
#  published by the Free Software Foundation; either version 3 of
#  the License, or (at your option) any later version.
#
#  GNOWSYS is distributed in the hope that it will be useful, but
#  WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public
#  License along with GNOWSYS (COPYING); if not, write to the
#  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
#  Boston, MA  02110-1301  USA59 Temple Place, Suite 330,
#
######################################################################


GNOWSYS is used for knowledge networking, semantic web applications
and knowledge management .  It is implemented in Python2.4 and
Postgresql and published as web services using XML-RPC deployed on the
Zope web server. For more details check out the docs folder or
lab.gnowledge.org .



EXECUTE THE BELOW GIVEN EXAMPLES USING XML-RPC			
================================================

import xmlrpclib con =
xmlrpclib.Server("http://username:password@hostadress:port/website/gnowql")


This is the sequence we follow:

Add two objectypes having nid's  as "Writer" and "Book"
Create relationtype having nid as "hasWritten" between "Writer" and "Book"
Add an attrbutetype with nid "hasName" to Objecttype "Writer".
Add an attrbutetype with nid "hasTitle" to Objecttype "Book".
Add an object with nid "Writer1" and make it an instance of "Writer".
Add an object with nid "Book1" and make it an instance of "Book".
Add a relation between "Writer1" and "Book1" with relationtype "hasWritten".
Add an attribute with value "Richard Dawkins" to "Writer1" with attributetype "hasName".
Add an attribute with value "The God Delusion" to "Book1" with attributetype "hasTitle".



Adding Objecttypes:
------------------


Adding an objecttype with nid Writer:

input = {
      'nodetype':'objecttype',
      'nid':'Writer',
      'status':'public',
      'subtypeof':['96'], # '96' is ssid of an objecttype, subtypeof key is not mandatory.  
      'attributes':[('title','writer'),('description','Writer is a person who writes')],
      'language':'english'
      }
print con.setnode(input)



Adding an objecttype with nid Book:

input = {
      'nodetype':'objecttype',
      'nid':'Book',
      'status':'public',
      'attributes':[('title','book'),('description','books')],
      'language':'english'
      }
print con.setnode(input)



RelationType:
------------


dictionary = {                                                                                                                      
                  'nodetype':'relationtype',                                                                                            
                  'nid':'hasWritten',                                                                              
                  'status':'Public',                                                                                                     
                  'inversename':'writerof',                                                                         
                  'subjecttype1':['writer'],                                                     
                  'subjecttype2':['book'],
		  'attributes':[('title','title for relationtype hasWritten'),('description','some description for relationtype hasWritten')],
		  'applicablenodetypes1':'tokens',
		  'applicablenodetypes2':'tokens'
		  }
con.setnode(dictionary)




AttributeType:
-------------

input = {
                'nodetype':'attributetype',
                'nid':'hasName',
                'status':'Public',
                'subjecttypes':['Writer'], 
                'restrictiontype':1,    
                'datatype':"varchar",    
                'regex':"some regular expression",
                'length':5,
                'range':'0-5',
                'precision':2
                 }
con.setnode( input )


input = {
                'nodetype':'attributetype',
                'nid':'hasTitle',
                'status':'Public',
                'subjecttypes':['Book'], 
                'restrictiontype':1,    
                'datatype':"varchar",    
                'regex':"some regular expression",
                'length':5,
                'range':'0-5',
                'precision':2
                 }
con.setnode( input )



Special case when the  restriction type is 0:


input = {
                'nodetype':'attributetype',
                'nid':'Languages',
                'status':'Public',
                'subjecttypes':['12'], 
                'restrictiontype':0,   
                'selectiontype':0,      
                'listid:'2'
               }
con.setnode( input )


More information regarding the Attributetypes can be obtained from the Attributetype.py file


Object:
------


input = {
      'nodetype':'object',
      'nid':'writer1',
      'status':'public',
      'instanceof':['11'],
      'relation':[('reltypenid',['list of ssids']),()],
      'attributes':[('title','some attributevalue1'),('hasName','some attributevalue2')],
      'structure':['10','12','13'],
      'language':'english'
       }
con.setnode(input)


input = {
      'nodetype':'object',
      'nid':'Book1',
      'status':'public',
      'instanceof':['12'],
      'relation':[('reltypenid',['list of ssids']),()],
      'attributes':[('description','some attributevalue1'),('hasTitle','some attributevalue2')],
      'structure':['14','15','16'],
      'language':'english'

       }
con.setnode(input)


NOTE: In the below given examples '17' is the ssid of the object 'Writer1' and '20' is the ssid of the object 'Book1'.   



Relation:
---------

input = {
         'nodetype':'relation',
         'status':'Public',
         'subject1':['17'],
         'subject2':['20'],
         'relationtypes':'hasWritten'
         }
con.setnode(input)



Attribute:
---------

input = {
            'nodetype':'attribute',
            'status':'Public',
            'instanceof':[('14',"Richard Dawkins")],
            'subject':'23',
            'language':'english'
            }
k=con.setnode(input)
return k

On success it will return you a list of list of format: [ [new ssid of the subject] , [all attribute ssids that are attached to this new ssid of subject] ].
for eg  for above , k=[['29'],['33']] where 29 is new ssid of subject 23 and 'Richard Dawkins' is the attribute value to whom ssid 33 is assigned.

input = {
            'nodetype':'attribute',
            'status':'Public',
            'instanceof':[('16',"The God Delusion")],
            'subject':'24',
            'language':'english'
            }
con.setnode(input)



###
NOTE: One can find the explanation for get methods from the gnowql.py file , every function has been given an explanation.
###





########################################
GNOWQL Methods
########################################




-- addUser( username , password )
   - adds a user in ZODB



-- addUserSQL( username , password ,fullname , email)
   - adds a user in the authentication tables of GNOWSYS



-- getUserId( )
   - gets the userid of the currently loggedin user.



-- setnode( dictionary)
   - sets a node in the database (more examples in SetMethods.py file)



-- setlist( dictionary )
   - Sets a list in the gnowledge base.Used for Attributetypes.
   - Example :
       	     Structure of the dictionary :
    	     dictionary = {
                 'nid':'languages',
                 'status':'public',
                 'datatype':'varchar[]',
                 'structure':['english','hindi','marathi'],
                 'language':'english'
                 }




-- setregex ( dictionary )
   - Sets a regular expression in the database , Used for Attributetypes
   - Example :
             dictionary = {
                 'regex':'ababab'
		 'description':'some description'
                 }



-- nidExists( nid )
   - Checks if the nid exists




-- getNodetype( ssid ) 
   - Returns nodetype given node ssid
   - example : getNodetype('253')
     output : gbattributes




-- getSelectionlist( )

   - This method returns all the selectionlists  in the gnowledge base . Used while attaching attributetypes.
   - FOR EXAMPLE : getSelectionlist()
   - OUTPUT : 
        
        [{'listid': '49', 'value': ['english', 'hindi', 'marathi'], 'nid': 'Languages'}, 
        {'listid': '74913', 'value': ['earth', 'jupiter', 'mars'], 'nid': 'Planets'}]

 


-- getRegex( )
   
   - This method returns all the regular expressions  in the gnowledge base . Used while attaching attributetypes.
   - FOR EXAMPLE : getRegex( )
   - OUTPUT : 
        [{'id': '0', 'exp': 'NO REGULAR EXPRESSION'}, 
        {'id': '1', 'exp': '\x08(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'}, 
        {'id': '2', 'exp': '\x08(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'}]



-- getAll( nodetype )
    
    - Accepts nodetype i.e, tablename and returns a dictionary with key as nid and value latestssid
    - FOR EXAMPLE : getAll('gbobjecttypes' )
    - OUTPUT : {'writer':'21','book':'32'} 
        
      


-- getNeighbourhood( ssid_list , getwhat )
    - gets the neighbourhood of the list of ssids provided
    - getwhat can take values rendered_nbh or nbh


-- getinfoFromSSID( ssid_list )
    - given a list of ssid returns entire rows/tuples.
        

-- getlatestssids( idlist , idtype)
     - idtype : idtype could be any one of nid, ssid, inid
     - idlist : idlist could be a list of nids or list of ssids or list of inids.
     - example : getlatestssids( ['11','12','13'] , idtype):



-- getAllSnapshots( idtype , id )
     - Gets all the snapshots(ssids) of the given node corresponding to input nid/ssid/inid.


-- getRoles( RTnid )

     - Given a relationtype nid this method returns the roles participating in the relationtype 
     - FOR EXAMPLE : getRoles('instanceof')
     - OUTPUT : 

        [ {'cardinality1': 0, 'cardinality2': 0, 'rtid': 1, 'applicablenodetypes2': 'gbusertypes,gbprocesstypes,gbobjecttypes,gbrelationtypes,gbattributetypes', 'applicablenodetypes1': 'gbusers,gbprocess,gbobjects,gbrelations,gbattributes', 'subjecttype1': 0L, 'subjecttype2': 0L}, 
        {'cardinality1': 0, 'cardinality2': 0, 'rtid': 2, 'applicablenodetypes2': 'gbmetatypes', 'applicablenodetypes1': 'gbusertypes,gbprocesstypes,gbobjecttypes,gbrelationtypes,gbattributetypes', 'subjecttype1': 0L, 'subjecttype2': 0L} ]
        



-- getSubjecttypes( ATnid)
       
      - Given a attributetype nid this method returns the subjecttypes participating in the attributetype 
      - FOR EXAMPLE : getSubjecttypes('Languages')
      - OUTPUT : 
        [{'stid': '19', 'applicablenodetypes': None}]

        So the subjecttype is 19 and the applicablenodetypes is None which means that the attribute would be attached
        to the instances of subjecttype with inid 19
        

-- getSelectionlist( )
        
      - This method returns all the selectionlists  in the gnowledge base . Used while attaching attributetypes.
      - FOR EXAMPLE : getSelectionlist()
      - OUTPUT : 
        
        [{'listid': '49', 'value': ['english', 'hindi', 'marathi'], 'nid': 'Languages'}, 
        {'listid': '74913', 'value': ['earth', 'jupiter', 'mars'], 'nid': 'Planets'}]

        

-- getRestrictions( ATlist ) 
        
       - Given list of attributetype ssids the method returns all the restrictions that the attributetypes have.
       - FOR EXAMPLE : getRestrictions( ['10','50','51'] )
       - OUTPUT : 
       	 
	 {{'10': {'datatype': 'varchar', 'range': None, 'precision': None, 'regexid': '0', 'length': None, 'type': '1'}, '51': {'datatype': 'float8[]', 'range': '0-5', 'precision': 2, 'regexid': '1', 'length': 5L, 'type': '1'}, '50': {'datatype': 'varchar[]', 'listid': 49L, 'type': '0', 'selectiontype': '0'}}

        
        
        
-- getAttributetypes( subjecttypelist ) 
       
       - Given list of subjecttype inids the method returns all the attributetypes attached.
       - FOR EXAMPLE :  getAttributetypes(['5']) 
       - OUTPUT : 
        {'5': ['6', '7', '8', '9', '10']}

        
        

-- getRelationtypes( subjecttypelist ) 
        
        - Given list of subjecttype inids the method returns all the relationtypes attached.
	- FOR EXAMPLE :  getRelationtypes(['11','38026']) 
	- OUTPUT : 
        {'11': ['12'], '38026': ['38028']}

        

-- getAttributeValues( Attrssidlist ) 
        
	- Given a list of attributessids returns their values.
	- example : getAttributeValues(['173','174','176']) 
        - output :
        {'173':'Richard Dawkins','174':'The God Delusion','176':['121','122','123']}



-- getSubtypes( nodeid ) 

        - Returns only the 'subtypes' of the node specified
	- For example : 
          If nodeid is 15 then the method returns only the subtypes of the 
          node provided



-- getInstances( nodeid ) 
        
        - Returns only the 'subtypes' of the node specified
	- For example : 
          If nodeid is 15 then the method returns only the instances of the 
          node provided

        
    
-- getAllSubtypes( nodeid ) 
       

        - Returns all the 'subtypes' of the node specified
	- For example : 
          If nodeid is 15 then the method returns all the subtypes of the 
          node provided
          ie If '15' has subtype '20' and and '20' has subtype '40' and '40' has subtype '60'.
          then getAllSubtypes( '15' ) would return ['20','40','60']
 

-- getAllInstances( nodeid ) 


        - Returns all the 'subtypes' of the node specified
	- For example : 
          If nodeid is 15 then the method returns all the instances of the 
          node provided
          The code has been divided into two parts :
          1) It gets all the subtypes first
            -- If '15' has subtype '20' and and '20' has subtype '40' and '40' has subtype '60'.
               then getAllSubtypes( '15' ) would return ['20','40','60']
	  2) Then from the list of subtypes it gets all the instances.
           -- i.e instances of 20,40 and 60
 
        

-- getAttributeValues( Attrssidlist )
        
	- Given a list of attributessids returns their values.
	- example : getAttributeValues(['173','174','176']) 
        - output :
        {'173':'Richard Dawkins','174':'The God Delusion','176':['121','122','123']}



-- getRelationids( ids )
        - ids : [['17','16'],['17','15']] where elements in the list are subject1,subject2 pair
	- output : {'19': [17L, 16L], '18': [17L, 15L]} 



Update Methods
==============


-- Update():
You can use the Update() to add/update attributes,structure and relations.
for eg: if there exists 2 objecttype with its ssid  OT1='15' and  OT2='16' and you add relation type between  them as:

input = {   
      'nodetype':'relationtype',
      'nid':'plays',
      'status':'Public',
      'inversename':'played by',
      'subjecttype1':['16'],
      'subjecttype2':['15'],
      'applicablenodetypes':'tokens'
}

context.gnowql.setnode(input)



And then you create objects as:
 input = {
      'nodetype':'object',
      'nid':'college',
      'uid':'1',
      'status':'public',
    'instanceof':['15']
       }
Object1ssid=context.gnowql.setnode(input)

(Object1ssid ='37' )

    input = {
      'nodetype':'object',
      'nid':'MIT',
      'uid':'1',
      'status':'public',
      'instanceof':['16'],
      'relation':[('FOUNDER',['37'])]
       }
Object2ssid= obj.setnode(input)
(Object2ssid =' 40' )



Now you can use Update() to do either of following:
1)add structure to the above created object.
2)add and update any attribute
3)create relation with some other object
4)any of the above combination




For example:
for the second object (ssid =40 ) we do:
1)modify attribute title from 'OWNER_CAR' to 'CAR_OWNER'
2)Add attribute description with value 'BORN:1855'
3)create a relation FOUNDER with another object whose ssid='46'
4)add structure to this object
 
input = {
            'status':'public',
            'attribute':[('11','CAR_OWNER'),('12','BORN:1955')],
            'subject':'40',
            'language':'en',
            'commit':'1',
            'structure':['only OWNER'],
            'relation':[('FOUNDER',['46'])]
           }

context.gnowql.Update(input)


------------ONLY STRUCTURE UPDATE --------------
For Example: you can update structure to it as
input = {
            'status':'public',
            'subject':'40',
            'nodetype':'user',
            'language':'en',
            'commit':'0',
            'structure':['11','12','122']
            }
return context.gnowql.Update(input)
The new ssid of the subject=27. 


-----------UPDATE STRUCTURE AND ATTRIBUTES---------
You can also update the structure and either of the attributes as :

input = {
            'status':'public',
            'subject':'40',
            'language':'en',
            'commit':'0',
            'structure':['111','012','122'],
            'attributes':[('6','rajiv')]
            }

return context.gnowql.Update(input)



DELETE Methods:
===============

eg:consider two OT types OT1 and OT2 with their ssids 16 and 17. There exists relationtype 'FOUNDER' between OT1 and OT2.
create 2 objects as:

input = {
      'nodetype':'object',
      'nid':'TRUSTY',
      'uid':'1',
      'status':'public',
      'instanceof':['17']
       }
The ssid of above object 'TRUSTY' =21

input = {
      'nodetype':'object',
      'nid':'OWNERVESIT',
      'uid':'1',
      'status':'public',
      'instanceof':['16'],
      'relation':[('FOUNDER',['21'])]
       }
the ssid of above created object='23'
Now if you want to delete the relation between object with ssids 21 and 23 you can do by :
1) call delete() with input dictionary as

input =  
    {
    'subject':'21',
    'status':'public',
    'uid':'1',
    'commit':'1',
    'relation':[('FOUNDER','rightroles', ['23'] )] #[(relntypenid,roleflag of subj2,[list of ssid])]
}


2)or 
   input=   {
    'subject':'23',
    'status':'public',
    'uid':'1',
    'commit':'1',
    'relation':[('FOUNDER','leftroles', ['21'] )] #[(relntypenid,roleflag of subj2,[list of ssid])]
   }



the above function will create 2 newsnapshot ,one for each object,i.e, new ssid for object with ssid=21 and 26 for 23.



If there are any attributes to delete from a particular node you can do it along with / without relation deletion
for eg: with relation deletion, delete attributes title,content that were attached to subject ssid=23; call delete() and pass input dictionary  to it.
input=   {
    'subject':'23',
    'status':'public',
    'uid':'1',
    'commit':'1',
    'relation':[('FOUNDER','leftroles', ['21'] )], #[(relntypenid,roleflag of subj2,[list of ssid])]
    'attributes': ['title','content']			   
   }

If you want to delete the node entire pass dictionary as:
input=   {
    'subject':'23',
    'status':'public',
    'uid':'1',
    'status':'deleted'
   }
   


One line examples on each method is included at the end of file GetMethods.py , SetMethods.py  , GeneralMethods.py . 

############################################################################################################################################################  EXAMPLE HOW TO USE THE RDF METHODS
############################################################################################################################################################

The RDF methods provide a means of translating  the Gnowsys  knowledge base into RDF files and vice versa . The import of generic triple stores into Gnowsys was its primary  motivation  but it also provides a good means of taking a backup of  data and schema  of Gnowsys  servers . Just like we take sql dumps of databases , we can now take  RDF dumps of databases and transfer it among servers .    Thus  easy sharing of ontologies is  possible .

n3_nbhexport(self,ssid,system) :Gives the neighbourhood of a node as n3 triples . Takes as input ssid and  stores the  output in the n3 folder in basepath .

n3_export(self,system) :Exports  an entire database or  ontology into  RDF in N3 form and stores it  in a file in the n3 folder .
System is the name of the ontology which should be exported . If it does not match with any ontology , the entire database is exported and stored in a file with the  filename same as the input system . 

n3_schema(self,system):Exports only the schema (types,restrictions and rules) of a system, which can be an ontology or the entire database into the n3 file.  

This function can be used to share ontologies . Suppose I have the 'sports' ontology stored on  Gnowsys server and someone else wants to use , but wants to add  his/her own objects and relations , they can just  use  con.n3_schema('sports') .  Thus a Gnowsys  ontology file (similar to  a OWL ontology file ) called as sports-schema.txt will be made in the n3 folder and can be shared easily .

If someone wants to  re-use the data as well as the schema  , they can use  con.n3_export('sports') .  Thus the entire sports triple  store  , the ontology as well as the objects will be  exported to  the file  sports.txt . This function calls n3_schema   implicitly so the file sports-schema.txt will also be made .  This function  serves as a way  of transfering triple stores from one server to another . 

These files can now be modified as per the users convenience ( he/she can add his/her own triples  to the n3 file and even extend the schema definition ). 
Then it can be reconstructed on another server , with all rules and  constraints intact . This serves as a  better way of transfering  knowledge bases and taking  backups  ,  because with sql dumps we can only reconstruct the database as it is . However with these n3 dumps we can modify  the files and then reconstruct it , or even  transfer just a part of the database . 

rdf_import(url,datapath,file,option,type): The above n3 files can be imported back into another gnowsys server using  this function . 
url  is the  url of the server . It must be on the localhost .
datapath  is the path of the file to be imported .
file is the schema file for the given  N3 file .   The file is validated against this schema file . This    is an optional parameter .
option can be  'file' or 'schema'. If it is 'file' all the data is taken from the parameter 'datapath' , if it is  'schema' then the data is taken from both the parameters .
Type is set to  'gnowsys' if the file has been  generated from a Gnowsys server or made by hand , but uses Gnowsys vocabulary . 
Type is set to 'owl' , if it is a generic file and uses a OWL  vocabulary .

Some notes :  The URL  in which all the triples are imported must point to any empty database .  You can point it to an already existing  database if thats what  you want  , then it will  add to the triples already present in the database .  Gnowsys vocabularies  for import must be in  N3 form and OWL vocabularies for import  must be in  XML form . 



        
