Imported Upstream version 0.3~20100924
[debian/pino.git] / src / twitter_create_dialog.vala
1 using Gtk;
2 using RestCustom;
3
4 namespace Twitter {
5
6 public class CreateDialog : CreateDialogGeneric {
7         
8         private Button auth_btn;
9         private Spinner tprogress;
10         private HBox a_box;
11         private Entry pin;
12         private Button access_btn;
13         private InfoBar acc_info;
14         
15         private weak Thread? request_token_thread = null;
16         private bool must_close = false;
17         private OAuthProxy proxy;
18         
19         private string root_url {get; set; default = "";}
20         public string s_token;
21         public string s_token_secret;
22         public string s_name;
23         public string s_avatar_url;
24         
25         public CreateDialog(Window parent, string root_url, string consumer_key,
26                 string consumer_secret, string icon_name, string service_name) {
27                 
28                 base(parent, _("Create %s account").printf(service_name), icon_name);
29                 
30                 debug(this.root_url);
31                 this.root_url = root_url;
32                 debug("ok");
33                 
34                 this.proxy = new OAuthProxy(consumer_key, consumer_secret,
35                         root_url, false);
36                 
37                 auth_btn = new Button();
38                 Image timg = new Image.from_stock(Gtk.STOCK_DIALOG_AUTHENTICATION,
39                         IconSize.MENU);
40                 Label tlabel = new Label(null);
41                 tlabel.set_markup("<i>%s</i>".printf(_("Authenticate in %s").printf(service_name)));
42                 tprogress = new Spinner();//Image.from_animation(progress);
43                 HBox btn_box = new HBox(false, 5);
44                 btn_box.pack_start(timg, false, false, 0);
45                 btn_box.pack_start(tlabel, false, true, 0);
46                 btn_box.pack_end(tprogress, false, true, 0);
47                 auth_btn.add(btn_box);
48                 
49                 auth_btn.clicked.connect(request_token_action);
50                 
51                 pin_info = new InfoBar();
52                 Label info_label = new Label(null);
53                 info_label.set_markup(_("<b>%s</b>".printf("Now enter PIN code and press the button")));
54                 pin_info.pack_start(info_label, false, false, 0);
55                 pin_info.reorder_child(info_label, 0);
56                 
57                 pin = new Entry();
58                 access_btn = new Button.with_label(_("Validate"));
59                 a_box = new HBox(false, 0);
60                 a_box.pack_start(pin, true, true, 0);
61                 a_box.pack_start(access_btn, false, false, 0);
62                 
63                 access_btn.clicked.connect(access_token_action);
64                 
65                 acc_info = new InfoBar();
66                 acc_img = new Image();
67                 acc_name = new Label(null);
68                 //acc_name.wrap_mode = Pango.WrapMode.WORD;
69                 //acc_name.set_ellipsize(Pango.EllipsizeMode.END);
70                 acc_info.pack_start(acc_img, false, false, 0);
71                 acc_info.pack_start(acc_name, true, true, 5);
72                 acc_info.reorder_child(acc_img, 0);
73                 acc_info.reorder_child(acc_name, 1);
74                 //acc_info.remove(acc_info.get_children().nth_data(2));
75                 
76                 HigTable auth_table = new HigTable(_("Authentication"));
77                 auth_table.add_widget_wide(auth_btn);
78                 auth_table.add_widget_wide(pin_info);
79                 auth_table.add_widget_wide(a_box);
80                 auth_table.add_widget_wide(acc_info);
81                 
82                 
83                 vbox.pack_start(auth_table, false, false, 5);
84                 vbox.show_all();
85                 
86                 //hidding some widgets
87                 tprogress.hide();
88                 pin_info.hide();
89                 a_box.hide();
90                 acc_info.hide();
91                 
92                 destroy.connect(() => {
93                         must_close = true;
94                         proxy.dispose();
95                 });
96         }
97         
98         private void request_token_action() {
99                 auth_btn.set_sensitive(false);
100                 tprogress.show();
101                 tprogress.start();
102                 
103                 try {
104                         request_token_thread = Thread.create(request_token, true);
105                         //jo = request_token_thread.join();
106                 } catch(ThreadError e) {
107                         debug(e.message);
108                 }
109         }
110         
111         private void access_token_action() {
112                 access_btn.set_sensitive(false);
113                 pin.set_sensitive(false);
114                 
115                 try {
116                         request_token_thread = Thread.create(access_token, true);
117                 } catch(ThreadError e) {
118                         debug(e.message);
119                 }
120         }
121         
122         private void* request_token() {
123                 bool answer = false;
124                 try {
125                         answer = OAuthProxy.request_token(proxy, "oauth/request_token", "oob");
126                 } catch (GLib.Error e) {
127                         debug(e.message); //TODO
128                 }
129                 
130                 if(!answer) {
131                         debug("request token is failed");
132                         
133                         if(must_close)
134                                 return null;
135                         
136                         auth_btn.set_sensitive(true);
137                         tprogress.hide();
138                         return null;
139                 }
140                 
141                 if(must_close)
142                         return null;
143                 
144                 Idle.add(() => {
145                         string token = OAuthProxy.get_token(proxy);
146                         token_received(token);
147                         return false;
148                 });
149                 
150                 return null;
151         }
152         
153         private void* access_token() {
154                 bool answer = false;
155                 
156                 try {
157                         answer = OAuthProxy.access_token(proxy, "oauth/access_token", pin.text);
158                 } catch(GLib.Error e) {
159                         debug(e.message); //TODO
160                 }
161                 
162                 if(!answer) {
163                         debug("access token is failed");
164                         
165                         return if_error();
166                 }
167                 
168                 if(must_close)
169                         return null;
170                 
171                 //fetching credentioals
172                 Rest.ProxyCall call = proxy.new_call();
173                 call.set_function("account/verify_credentials.xml");
174                 call.set_method("GET");
175                 
176                 try {
177                         answer = call.sync();
178                 } catch(GLib.Error e) {
179                         debug(e.message); //TODO
180                         
181                         return if_error();
182                 }
183                 
184                 if(!answer) {
185                         debug("access token is failed");
186                         
187                         return if_error();
188                 }
189                 
190                 debug(call.get_payload());
191                 
192                 Rest.XmlParser parser = new Rest.XmlParser();
193                 Rest.XmlNode root = parser.parse_from_data(call.get_payload(),
194                         (int64) call.get_payload().size());
195                 
196                 foreach(var val in root.children.get_values()) {
197                         Rest.XmlNode node = (Rest.XmlNode) val;
198                         if(node.name == "profile_image_url") {
199                                 this.s_avatar_url = node.content;
200                                 string? acc_img_path = img_cache.download(node.content);
201                                 if(acc_img_path != null)
202                                         acc_img.set_from_file(acc_img_path);
203                         }
204                         
205                         if(node.name == "screen_name") {
206                                 this.s_name = node.content;
207                                 acc_name.set_markup(_("Hello, <b>%s</b>!\nPress 'OK' to add this account".printf(node.content)));
208                         }
209                 }
210                 
211                 if(must_close)
212                         return null;
213                 
214                 acc_info.show();
215                 
216                 Idle.add(() => {
217                         this.s_token = OAuthProxy.get_token(proxy);
218                         this.s_token_secret = OAuthProxy.get_token_secret(proxy);
219                         
220                         ok_btn.set_sensitive(true);
221                         
222                         return false;
223                 });
224                                 
225                 return null;
226         }
227         
228         /* When we got a token */
229         private void token_received(string token) {
230                 debug(token);
231                 
232                 //open link in a browser
233                 GLib.Pid pid;
234                 
235                 try {
236                         GLib.Process.spawn_async(".", {"/usr/bin/xdg-open",
237                                 root_url + "oauth/authorize?oauth_token=" + token}, null,
238                                 GLib.SpawnFlags.STDOUT_TO_DEV_NULL, null, out pid);
239                 } catch(GLib.SpawnError e) {
240                         debug(e.message); //TODO
241                 }
242                 
243                 tprogress.hide();
244                 pin_info.show();
245                 a_box.show();
246                 
247                 set_focus(pin);
248         }
249         
250         private void* if_error() {
251                 if(must_close)
252                         return null;
253                 
254                 access_btn.set_sensitive(true);
255                 pin.set_sensitive(true);
256                 return null;
257         }
258 }
259
260 }