List of commits:
Subject Hash Author Date (UTC)
Started adding possibility to save in database. cf28a7731335cd1ffd2ebd03cc2e890c25e1c64b Detche 2016-11-13 19:43:21
Changed db interface and users/groups models. d0fdf8873a107c44d6acbef5cbffc869461d9aab Detche 2016-11-03 15:22:10
Changed UserId from element to attribute. 5407592cba9e7488519e069927a8ffb9ed32fdf6 Detche 2016-11-02 15:02:30
Added tasks system. 13bbf9857a0a61d5e2b0fd9483f5efd235cbd4f2 Detche 2016-11-02 14:58:20
Modified Knowledge process. Fixed indent 28e52095a297cbb0e6b9b6d799bb80ebe52828c1 Detche 2016-10-23 12:11:30
Updated README 8e298151286ec3cb4df29633aaca90fc871f2e80 Detche 2016-10-23 10:10:45
Update README.rst 7965df28cbef557fd3819919b4d44f0733dcecf0 Guillaume 2016-10-23 00:06:05
Added README page 8339ac5b13803b026dbfc5edd77fa50a24a70ecb Detche 2016-10-22 23:47:05
Added comments to sources. ce6491ef1337ea34d33b7e4ede0eb9f634e7ab1a Detche 2016-10-22 23:32:26
Added examples. Modified reaction class to add triggers. 545a35d1c5bb36e1b4e4d818b0e6a8f6642a222f Detche 2016-10-22 20:56:54
Initial commit 2cd79df6224290a994b1453f0327740816b0f632 Detche 2016-10-21 16:21:02
Commit cf28a7731335cd1ffd2ebd03cc2e890c25e1c64b - Started adding possibility to save in database.
Author: Detche
Author date (UTC): 2016-11-13 19:43
Committer name: Detche
Committer date (UTC): 2016-11-13 19:43
Parent(s): d0fdf8873a107c44d6acbef5cbffc869461d9aab
Signing key:
Tree: bf07a8a4acb2cdc9dd4dd075df6c21749a1920c6
File Lines added Lines deleted
botly/db.py 97 4
botly/users.py 10 0
File botly/db.py changed (mode: 100644) (index 5789619..afef9d7)
... ... from lxml import etree
7 7 class Db: class Db:
8 8
9 9 dbxml = False dbxml = False
10 dbpath = ""
11 dbmodified = False
10 12
11 13 def __init__(self): def __init__(self):
12 14 assert False, "No instance of this class should be created." assert False, "No instance of this class should be created."
 
... ... class Db:
15 17 def load(cls, filePath): def load(cls, filePath):
16 18 """Loads the database XML file at given path.""" """Loads the database XML file at given path."""
17 19 cls.dbxml = etree.parse(filePath) cls.dbxml = etree.parse(filePath)
20 cls.dbpath = filePath
21
22 @classmethod
23 def save(cls, filePath=''):
24 """Saves the database on the filesystem."""
25 if not cls.dbmodified:
26 return False
27 if not len(filePath):
28 filePath = cls.dbpath
29 cls.dbxml.write(filePath, encoding="utf-8", xml_declaration=True)
30 cls.dbmodified = False
31 return True
32
33 @classmethod
34 def was_modified(cls):
35 """Returns whether or not the DB was modified an require a save."""
36 return cls.dbmodified
18 37
19 38 def get_node(self, path): def get_node(self, path):
20 39 """Returns the node at the given absolute path""" """Returns the node at the given absolute path"""
21 40 return Db.dbxml.xpath(path)[0] return Db.dbxml.xpath(path)[0]
22
41
23 42 def is_loaded(self): def is_loaded(self):
24 43 """Returns whether or not the database was loaded.""" """Returns whether or not the database was loaded."""
25 44 return Db.dbxml != False return Db.dbxml != False
26 45
46 def store_value(self, valueName, value, parentXpath = ''):
47 """Stores a single value in the database."""
48 self._pre_check()
49
50 # If we provided a parent path, we use it, otherwise, use root
51 if len(parentXpath):
52 parent = self.root.xpath(parentXpath)
53 if len(parent):
54 parent = parent[0]
55 else:
56 return None
57 else:
58 parent = self.root
59
60 # If value exists in this parent, remove it. Then we create it
61 elem = parent.find(valueName)
62 if elem is not None:
63 parent.remove(elem)
64 elem = etree.Element(valueName)
65 elem.text = value
66 parent.append(elem)
67
68 self._set_modified(True)
69 return True
70
27 71 def query_value(self, valueName, parentPath = None): def query_value(self, valueName, parentPath = None):
28 72 """Loads a single value from the given parent.""" """Loads a single value from the given parent."""
29 73 self._pre_check() self._pre_check()
 
... ... class Db:
33 77 if parentPath is None: if parentPath is None:
34 78 parent = self.root parent = self.root
35 79 else: else:
36 parent = self.root.xpath(parentXpath)[0]
37
80 parent = self.root.xpath(parentXpath)
81 if len(parent):
82 parent = parent[0]
83 else:
84 return None
85
86 # Now query the value amoung the parent' subelements
38 87 if parent is not None: if parent is not None:
39 print(parent)
40 88 valueElem = parent.find(valueName) valueElem = parent.find(valueName)
41 89 if valueElem is not None and valueElem.text is not None: if valueElem is not None and valueElem.text is not None:
42 90 return valueElem.text return valueElem.text
43 91 return None return None
44 92
93 def store_object(self, parentXpath, obj):
94 """Store a single object in the db."""
95 self._pre_check()
96
97 parent = self.root.xpath(parentXpath)[0]
98 if parent is not None:
99 # Is the object already in the db? If so, remove it
100 for child in parent.iterchildren():
101 if child.get('Id') == obj['Id']:
102 parent.remove(child)
103 break
104 # Now save the object
105 parent.append(self._obj_to_xml(obj))
106 self._set_modified(True)
107 return True
108 return False
109
45 110 def query_object(self, parentXpath, objectId): def query_object(self, parentXpath, objectId):
46 111 """Loads a single object identified by its Id. None if not found.""" """Loads a single object identified by its Id. None if not found."""
47 112 self._pre_check() self._pre_check()
 
... ... class Db:
66 131 return objects return objects
67 132 return None return None
68 133
134 def _set_modified(self, modified):
135 Db.dbmodified = modified
136
137 def _obj_to_xml(self, obj):
138 """Create an xml element out of an object (dictionary)"""
139 elem = etree.Element(obj['Type'])
140 for key, value in obj.items():
141 if key == 'Id':
142 elem.set(key, value)
143 elif key == 'Type':
144 # We already used that value to name the element's tag
145 continue
146 elif isinstance(value, list):
147 # We found a list so loop through every value and create a
148 # child list elem. Its name is based on its parent's
149 childElem = etree.Element(key)
150 for lvalue in value:
151 listElem = etree.Element(key[:-1])
152 listElem.text = lvalue
153 childElem.append(listElem)
154 elem.append(childElem)
155 else:
156 childElem = etree.Element(key)
157 childElem.text = value
158 elem.append(childElem)
159 return elem
160
69 161 def _load_object_values(self, xmlobj): def _load_object_values(self, xmlobj):
70 162 """Loads the given xml node in a dictionary, considered as an object. """Loads the given xml node in a dictionary, considered as an object.
71 163
 
... ... class Db:
81 173
82 174 obj = {} obj = {}
83 175 obj['Id'] = xmlobj.get('Id') obj['Id'] = xmlobj.get('Id')
176 obj['Type'] = xmlobj.tag
84 177 for child in xmlobj.iterchildren(): for child in xmlobj.iterchildren():
85 178 if len(child) == 0: if len(child) == 0:
86 179 # We have no children, this node is value # We have no children, this node is value
File botly/users.py changed (mode: 100644) (index c125b44..c119446)
... ... class Users(Db):
33 33 user = self.query_object('Users', userid) user = self.query_object('Users', userid)
34 34 return user return user
35 35
36 def set(self, userid, valueName, value):
37 """Modify the user valueName with given value."""
38 user = self.get(userid)
39 # TODO
40 pass
41
36 42 def get_all(self): def get_all(self):
37 43 """Returns all users from the database.""" """Returns all users from the database."""
38 44 users = self.query_object_list('Users') users = self.query_object_list('Users')
 
... ... class Users(Db):
40 46 self.userCache = users self.userCache = users
41 47 return users return users
42 48
49 def _new_user(self, userid):
50 # TODO
51 pass
52
43 53 def _get_cached_user(self, userid): def _get_cached_user(self, userid):
44 54 """Returns the cached user if it exists, None otherwise.""" """Returns the cached user if it exists, None otherwise."""
45 55 for user in self.userCache: for user in self.userCache:
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/detche/Botly

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/detche/Botly

Clone this repository using git:
git clone git://git.rocketgit.com/user/detche/Botly

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main