Imported Upstream version 0.2.1
[debian/pino.git] / src / accounts.vala
1 /* accounts.vala
2  *
3  * Copyright (C) 2009-2010  troorl
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Author:
19  *      troorl <troorl@gmail.com>
20  */
21
22 using Xml;
23 using Gee;
24
25 namespace Auth {
26
27 public class Account : Object {
28         
29         private string _login;
30         public string login {
31                 get { return _login; }
32                 set { _login = value; }
33         }
34         
35         private string _password;
36         public string password {
37                 get { return _password; }
38                 set { _password = value; }
39         }
40         
41         private string _service;
42         public string service {
43                 get { return _service; }
44                 set { _service = value; }
45         }
46         
47         private string _proxy = "";
48         public string proxy {
49                 get { return _proxy; }
50                 set { _proxy = value; }
51         }
52         
53         private bool _active;
54         public bool active {
55                 get { return _active; }
56                 set { _active = value; }
57         }
58         
59         public Account.with_data(string __login, string __password, string __service,
60                 bool __active) {
61                 _login = __login;
62                 _password = __password;
63                 _service = __service;
64                 _active = __active;
65         }
66 }
67
68 public class Accounts : Object {
69         
70         private ArrayList<Account?> acc_lst;
71         public ArrayList<Account?> accounts {
72                 get { return acc_lst; }
73         }
74         
75         private string acc_file_path;
76         public bool is_new;
77         
78         public signal void changed(string hash);
79         public signal void active_changed();
80         
81         public Accounts() {
82                 acc_lst = new ArrayList<Account?>();
83                 load();
84         }
85         
86         /* load accounts from file */
87         private void load() {
88                 string conf_dir = Environment.get_home_dir() + "/.config/";
89                 
90                 var dir = File.new_for_path(conf_dir);
91                 if(!dir.query_exists(null))
92                         dir.make_directory(null);
93                 
94                 string pino_dir = conf_dir + "/pino";
95                 
96                 dir = File.new_for_path(pino_dir);
97                 if(!dir.query_exists(null))
98                         dir.make_directory(null);
99                 
100                 dir = null;
101                 
102                 //checking for settings file and creating if necessary
103                 acc_file_path = pino_dir + "/accounts.xml";
104                 var acc_file = File.new_for_path(acc_file_path);
105                 
106                 if(!acc_file.query_exists(null)) {
107                         //var pref_stream = pref_file.create(FileCreateFlags.NONE, null);
108                         is_new = true;
109                         return;
110                 }
111                 
112                 //reading content
113                 string content;
114                 {
115                         var stream = new DataInputStream(acc_file.read(null));
116                         content = stream.read_until("", null, null);
117                 }
118                 
119                 parse(content);
120         }
121         
122         /* parse xml file */
123         private void parse(string data) {
124                 Xml.Doc* xmlDoc = Parser.parse_memory(data, (int)data.size());
125                 Xml.Node* rootNode = xmlDoc->get_root_element();
126                 
127                 for(Xml.Node* iter = rootNode->children; iter != null; iter = iter->next) {
128                         if(iter->type != ElementType.ELEMENT_NODE)
129                                 continue;
130                         
131                         if(iter->name == "account") {
132                                 if(iter->children != null) {
133                                         Account acc = new Account();
134                                         
135                                         Xml.Node *iter_in;
136                                     
137                                     for(iter_in = iter->children->next; iter_in != null; iter_in = iter_in->next) {
138                                         if(iter_in->is_text() != 1) {
139                                                 switch(iter_in->name) {
140                                                         case "login":
141                                                                 acc.login = iter_in->get_content();
142                                                                 break;
143                                                         
144                                                         case "password":
145                                                                 acc.password = iter_in->get_content();
146                                                                 break;
147                                                         
148                                                         case "service":
149                                                                 acc.service = iter_in->get_content();
150                                                                 break;
151                                                         
152                                                         case "proxy":
153                                                                 acc.proxy = iter_in->get_content();
154                                                                 break;
155                                                         
156                                                         case "active":
157                                                                 acc.active = iter_in->get_content().to_bool();
158                                                                 break;
159                                                 }
160                                         }
161                                     }
162                                     delete iter_in;
163                                     acc_lst.add(acc);
164                                 }
165                         }
166                 }
167         }
168         
169         /* save accounts to the file */
170         public void write() {
171                 Xml.Doc* xmldoc = new Xml.Doc("1.0");
172                 Xml.Ns* ns = new Xml.Ns(null, null, null);
173                 ns->type = Xml.ElementType.ELEMENT_NODE;
174                 Xml.Node* root = new Xml.Node(ns, "accounts");
175                 xmldoc->set_root_element(root);
176                 
177                 root->add_content("\n");
178                 
179                 foreach(Account acc in acc_lst) {
180                         Xml.Node* iter;
181                         iter = root->new_child(ns, "account");
182                         
183                         iter->add_content("\n\t");
184                         iter->new_text_child(ns, "login", acc.login);
185                         iter->add_content("\n\t");
186                         iter->new_text_child(ns, "password", acc.password);
187                         iter->add_content("\n\t");
188                         iter->new_text_child(ns, "service", acc.service);
189                         iter->add_content("\n\t");
190                         iter->new_text_child(ns, "proxy", acc.proxy);
191                         iter->add_content("\n\t");
192                         iter->new_text_child(ns, "active", acc.active.to_string());
193                         iter->add_content("\n");
194                         root->add_content("\n");
195                 }
196                 
197                 //write this document to the accounts file
198                 var stream = FileStream.open(acc_file_path, "w");
199                 xmldoc->dump(stream);
200         }
201         
202         /* return current account */
203         public Account? get_current_account() {
204                 foreach(Account acc in acc_lst) {
205                         if(acc.active)
206                                 return acc;
207                 }
208                 
209                 //return first
210                 if(acc_lst.size > 0) {
211                         var acc = acc_lst.get(0);
212                         acc.active = true;
213                         write();
214                         return acc;
215                 }
216                 else
217                         return null;
218         }
219         
220         /* add new account */
221         public void add_account(Account acc) {
222                 acc_lst.add(acc);
223                 //write();
224         }
225         
226         /* delete account by index */
227         public void delete_account(string hash) {
228                 acc_lst.remove(get_by_hash(hash));
229         }
230         
231         /* set one active account */
232         public void set_active_account(string hash) {
233                 foreach(Account acc in acc_lst) {
234                         acc.active = false;
235                 }
236                 
237                 get_by_hash(hash).active = true;
238                 
239                 active_changed(); // send signal
240         }
241         
242         /* changing account */
243         public void change_account(int index, Account acc) {
244                 acc_lst.set(index, acc);
245         }
246         
247         /* get account by login+service+proxy */
248         public Account get_by_hash(string hash) {
249                 foreach(Account acc in acc_lst) {
250                         if(acc.login + acc.service + acc.proxy == hash)
251                                 return acc;
252                 }
253                 
254                 return null;
255         }
256 }
257
258 }