Merge lp:~ebanyash/cable/cable-e into lp:cable

Proposed by Evan Banyash
Status: Merged
Approved by: Akshay Shekher
Approved revision: 17
Merge reported by: Akshay Shekher
Merged at revision: not available
Proposed branch: lp:~ebanyash/cable/cable-e
Merge into: lp:cable
Diff against target: 1271 lines (+483/-335)
10 files modified
.bzrignore (+2/-0)
CMakeLists.txt (+4/-3)
INSTALL (+3/-3)
bin/quickbuild.sh (+11/-0)
src/Backend.vala (+0/-215)
src/Cable.vala (+37/-37)
src/Global.vala (+4/-4)
src/Widgets/Room.vala (+40/-40)
src/Widgets/Server.vala (+37/-33)
src/doodleIRC.vala (+345/-0)
To merge this branch: bzr merge lp:~ebanyash/cable/cable-e
Reviewer Review Type Date Requested Status
Akshay Shekher (community) Approve
Evan Banyash (community) Approve
elementary Apps team Pending
Review via email: mp+163713@code.launchpad.net

Description of the change

I changed the installation instructions to be more correct, brought in voldyman's functional backend and credited him for it.

This is important because as of now, the project's trunk is non-functional. It crashes upon trying to join a channel.

To post a comment you must log in.
Revision history for this message
Akshay Shekher (voldyman) wrote :

nice work.
please change the permissions of the files to -x from +x.

review: Needs Fixing
Revision history for this message
Evan Banyash (ebanyash) wrote :

And... done.

This is how you use the "Resubmit" review type, right?

review: Needs Resubmitting
Revision history for this message
Evan Banyash (ebanyash) wrote :

> And... done.
>
> This is how you use the "Resubmit" review type, right?

...No, apparently it is not.
Sorry, I'm a bit GNU here.

review: Approve
Revision history for this message
Akshay Shekher (voldyman) wrote :

my mistake, i meant remove the executable attribute (make all fines -x)

and your last commit is empty.

review: Needs Fixing
lp:~ebanyash/cable/cable-e updated
11. By Evan Banyash

small update to root cmakelists

12. By Evan Banyash

Okay, -x on everything now

13. By Evan Banyash

merging to avoid conflicting branches, apparently

Revision history for this message
Evan Banyash (ebanyash) wrote :

> my mistake, i meant remove the executable attribute (make all fines -x)
>
> and your last commit is empty.

Yeah, I guess it was empty because everything was already +x. I thought that was normal when just changing permissions. I guess not. Okay, it should all be -x now except the directories because apparently you can't really use them without the execute bit.

Revision history for this message
Akshay Shekher (voldyman) wrote :

for the backend, could you get the latest one from github.com/voldyman/doodleIRC ?

that would be the ultimate merge :)

Revision history for this message
Evan Banyash (ebanyash) wrote :

> for the backend, could you get the latest one from
> github.com/voldyman/doodleIRC ?
>
> that would be the ultimate merge :)

Good idea. I'll see what I can do.

Hopefully nothing will break too bad.

Revision history for this message
Evan Banyash (ebanyash) wrote :

Hmm... do you suggest that I keep doodleIRC.vala intact and change the server widget? Then we'd have two namespaces in the project. Is that okay? Or should I change the namespace of doodleIRC.vala to be in Cable?

Revision history for this message
Akshay Shekher (voldyman) wrote :

You could keep it intact so the frontend and back end will be separate and
easier to update later.
On May 16, 2013 7:20 PM, "Evan Banyash" <email address hidden> wrote:

> Hmm... do you suggest that I keep doodleIRC.vala intact and change the
> server widget? Then we'd have two namespaces in the project. Is that okay?
> Or should I change the namespace of doodleIRC.vala to be in Cable?
> --
> https://code.launchpad.net/~ebanyash/cable/cable-e/+merge/163713
> You are reviewing the proposed merge of lp:~ebanyash/cable/cable-e into
> lp:cable.
>

lp:~ebanyash/cable/cable-e updated
14. By Evan Banyash

Moved to latest DoodleIRC backend

15. By Evan Banyash

Deleted the old Backend.vala

Revision history for this message
Evan Banyash (ebanyash) wrote :

And, done. Everything appears to still work, too!

review: Approve
lp:~ebanyash/cable/cable-e updated
16. By Evan Banyash

okay, I forgot to add this last time. Whew, crisis over

17. By Evan Banyash

added a script to build and test at super fast speeds

Revision history for this message
Akshay Shekher (voldyman) wrote :

very good work.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.bzrignore'
2--- .bzrignore 1970-01-01 00:00:00 +0000
3+++ .bzrignore 2013-05-17 01:15:34 +0000
4@@ -0,0 +1,2 @@
5+build
6+*~
7\ No newline at end of file
8
9=== modified file 'CMakeLists.txt'
10--- CMakeLists.txt 2012-10-25 19:43:33 +0000
11+++ CMakeLists.txt 2013-05-17 01:15:34 +0000
12@@ -1,6 +1,6 @@
13 # Check http://webdev.elementaryos.org/docs/developer-guide/cmake for documentation
14
15-project (agenda)
16+project (cable)
17 cmake_minimum_required (VERSION 2.8)
18 cmake_policy (VERSION 2.6)
19
20@@ -41,7 +41,7 @@
21
22 include(ValaPrecompile)
23 vala_precompile(VALA_C
24- src/Backend.vala
25+ src/doodleIRC.vala
26 src/Cable.vala
27 src/Global.vala
28 src/Settings.vala
29@@ -52,6 +52,7 @@
30 PACKAGES
31 granite
32 OPTIONS
33+ --target-glib=2.32
34 --vapidir=${CMAKE_CURRENT_SOURCE_DIR}/vapi/
35 )
36
37@@ -64,4 +65,4 @@
38
39 install(TARGETS cable RUNTIME DESTINATION bin)
40 install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/cable.desktop DESTINATION share/applications)
41-#install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/agenda.svg DESTINATION share/icons/hicolor/48x48/apps)
42+#install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/cable.svg DESTINATION share/icons/hicolor/48x48/apps) And this is where I'd put my icon... IF I HAD ONE
43
44=== modified file 'INSTALL'
45--- INSTALL 2012-08-22 15:00:43 +0000
46+++ INSTALL 2013-05-17 01:15:34 +0000
47@@ -9,10 +9,10 @@
48 gdk-x11-3.0
49
50 Installation:
51- bzr branch lp:eidete
52- cd eidete
53+ bzr branch lp:cable
54+ cd cable
55 mkdir build
56 cd build
57- cmake .. -DCMAKE_INSTALL_PREFIX
58+ cmake ..
59 make
60 sudo make install
61
62=== added directory 'bin'
63=== added file 'bin/quickbuild.sh'
64--- bin/quickbuild.sh 1970-01-01 00:00:00 +0000
65+++ bin/quickbuild.sh 2013-05-17 01:15:34 +0000
66@@ -0,0 +1,11 @@
67+#!/bin/sh
68+#
69+#
70+mkdir ../build;
71+cd ../build;
72+rm -rf *;
73+cmake ..;
74+make;
75+cd ../bin;
76+ln ../build/cable cable;
77+./cable
78\ No newline at end of file
79
80=== removed file 'src/Backend.vala'
81--- src/Backend.vala 2012-10-25 19:43:33 +0000
82+++ src/Backend.vala 1970-01-01 00:00:00 +0000
83@@ -1,215 +0,0 @@
84-
85-namespace Cable.Backend {
86-
87- public class Server {
88- public List<string> chans;
89- string nick;
90- string server_url;
91- User user;
92- SocketConnection connection;
93- unowned Thread<int> thread;
94- bool connected;
95- List<string> to_send;
96-
97- public Server (string url, User user, string nick) {
98- this.server_url = url;
99- this.user = user;
100- this.nick = nick;
101-
102- this.chans = new List<string> ();
103- connected = false;
104- to_send = new List<string> ();
105-
106- on_connect_complete.connect (() =>{
107- to_send.foreach ((cmd) => {
108- print ("Sending "+cmd);
109- raw_send (cmd);
110- to_send.remove (cmd);
111- });
112-
113- });
114- }
115-
116- ~DoodleIRCServer () {
117- quit_server ("Client Quit");
118- Thread.exit (1);
119-
120- }
121-
122- public void change_nick (string chan, string nick) {
123- this.nick = nick;
124- raw_send ("NICK %s\r\n".printf (this.nick));
125- }
126-
127- public void connect () {
128- if (!connected) {
129- try {
130- thread = Thread.create<int> (this.loop, false);
131- } catch (Error e) {
132- error ("Could Not Start Thread: %s".printf (e.message));
133- }
134- }
135- }
136-
137-
138- public int loop () {
139-
140- try {
141- // Resolve hostname to IP address
142- var resolver = Resolver.get_default ();
143- var addresses = resolver.lookup_by_name (this.server_url, null);
144- var address = addresses.nth_data (0);
145- print ("Resolved %s to %s\n".printf (this.server_url, address.to_string ()));
146-
147- // Connect
148- var client = new SocketClient ();
149- connection = client.connect (new InetSocketAddress (address, 6667));
150- print ("Connected to %s\n".printf (this.server_url));
151-
152- // Send USER request
153- var message = "USER %s %s %s :%s\r\n".printf (user.username, user.hostname,
154- user.servername, user.realname);
155- raw_send (message);
156- print ("Wrote request USER\n");
157-
158- // Send NICK request
159- message = "NICK %s\r\n".printf (nick);
160- raw_send (message);
161- print ("Wrote nick request\n");
162-
163- var response = new DataInputStream (connection.input_stream);
164-
165- on_connect_complete ();
166- connected = true;
167- // Receive response
168- string line="", msg="", sender="" , chan="" , cmd="" ;
169- while (true) {
170- line = response.read_line (null).strip ();
171- if (line[0] == ':')
172- parse_line (line, out sender,out cmd, out chan, out msg);
173- else {
174- cmd = line.split (" ")[0].strip ();
175- }
176- switch (cmd) {
177- case "PING":
178- print ("pinged\n");
179- raw_send (line.replace("PING","PONG"));
180- break;
181- case "NOTICE":
182- print ("Noice: "+msg.strip ()+"\n");
183- on_notice (msg.strip ());
184- break;
185- case "PRIVMSG":
186- print ("Chan-> "+chan+"\nMSG-> "+msg+"\n");
187- on_message (sender, chan, msg);
188- break;
189-
190- case "QUIT":
191- print (" %s has quit\n".printf (sender));
192- break;
193-
194- case "JOIN":
195- print ("User has Joined");
196- on_user_join (chan, nick);
197- break;
198-
199- case "433": // nick name is use
200- change_nick (chan,this.nick+"_");
201- rejoin_channels ();
202- break;
203- case "353":
204- on_names_listed (msg.split (" "));
205- break;
206- default:
207- print (line+"\n\n\n");
208- break;
209- }
210-
211- }
212- } catch (Error e) {
213- stderr.printf ("%s\n", e.message);
214- }
215- return 0;
216- }
217-
218- private void raw_send (string line) {
219- try {
220- connection.output_stream.write (line.data);
221- connection.output_stream.flush ();
222- } catch (Error e) {
223- error ("raw_send: %s".printf (e.message));
224- }
225- }
226-
227- void parse_line (string line, out string sender,out string cmd, out string chan, out string msg) {
228- //split the message from the info
229- var first_split = line.split (":");
230- var info = first_split[1];
231- //msg = join_str_ar (2, first_split.length, first_split);
232- msg = line.split (" :")[1];
233-
234- //split the info to extract sender and chan
235- var second_split = info.split (" ");
236- cmd = second_split[1].strip ();
237- chan = second_split[2].strip ();
238- sender = second_split[0].strip ();
239- }
240-
241- private void process_message () {
242-
243- }
244-
245- public void send (string cmd) {
246- if (connected)
247- raw_send (cmd);
248- else
249- to_send.append (cmd);
250- }
251- private void rejoin_channels () {
252- // Send JOIN request
253- foreach (string chan in chans) {
254- join_chan (chan);
255- print ("Wrote request to join %s\n".printf (chan));
256- }
257- }
258- public void kick_user (string chan, string user, string reason) {
259- send ("KICK %s %s :%s\r\n".printf (chan, user, reason));
260- }
261-
262- public void join_chan (string chan) {
263- send ("JOIN %s\r\n".printf (chan));
264- chans.append (chan);
265- }
266-
267- public void quit_server (string message) {
268- send ("QUIT :%s\r\n".printf (message));
269- }
270-
271- public void exit_chan (string chan) {
272- send ("PART %s\r\n".printf (chan));
273- }
274-
275- public void write (string chan, string msg) {
276- send ("PRIVMSG %s :%s\r\n".printf (chan, msg));
277- }
278-
279- public void get_names (string chan) {
280- send ("NAMES %s\r\n".printf(chan));
281- }
282-
283- //public void
284- public signal void on_connect_complete ();
285- public signal void on_message (string sender, string chan, string msg);
286- public signal void on_notice (string notice);
287- public signal void on_error (string error_msg);
288- public signal void on_user_join (string chan, string nick);
289- public signal void on_names_listed (string[] names);
290- }
291-
292- public struct User {
293- public string username;
294- public string hostname;
295- public string servername;
296- public string realname;
297- }
298-}
299
300=== modified file 'src/Cable.vala'
301--- src/Cable.vala 2012-10-25 19:43:33 +0000
302+++ src/Cable.vala 2013-05-17 01:15:34 +0000
303@@ -7,39 +7,39 @@
304 {
305 program_name = "Cable";
306 exec_name = "cable";
307-
308+
309 build_data_dir = Constants.DATADIR;
310 build_pkg_data_dir = Constants.PKGDATADIR;
311 build_release_name = Constants.RELEASE_NAME;
312 build_version = Constants.VERSION;
313 build_version_info = Constants.VERSION_INFO;
314-
315+
316 app_years = "2012";
317 app_icon = "applications-chat";
318 app_launcher = "cable.desktop";
319 application_id = "net.launchpad.cable";
320-
321+
322 main_url = "https://code.launchpad.net/cable";
323 bug_url = "https://bugs.launchpad.net/cable";
324 help_url = "https://code.launchpad.net/cable";
325 translate_url = "https://translations.launchpad.net/cable";
326-
327- about_authors = {"Tom Beckmann <tombeckmann@online.de>"};
328+
329+ about_authors = {"Tom Beckmann <tombeckmann@online.de>", "Akshay Shekher <voldyman666@gmail.com"};
330 about_documenters = {"Tom Beckmann <tombeckmann@online.de>"};
331 about_artists = {"Harvey Cabaguio"};
332 about_comments = "Development release, not all features implemented";
333 about_translators = "";
334 about_license_type = Gtk.License.GPL_3_0;
335 }
336-
337+
338 Gtk.Window window;
339 public Granite.Widgets.SourceList servers;
340 public Gtk.EventBox display_box;
341-
342+
343 public App ()
344 {
345 }
346-
347+
348 void build ()
349 {
350 window = new Gtk.Window ();
351@@ -49,33 +49,33 @@
352 servers = new Granite.Widgets.SourceList ();
353 var menu = new Gtk.Menu ();
354 display_box = new Gtk.EventBox ();
355-
356+
357 var join_channel = new Gtk.ToolButton (new Gtk.Image.from_icon_name ("internet-web-browser", Gtk.IconSize.LARGE_TOOLBAR), _("Join a Channel"));
358 var add_server = new Gtk.ToolButton (new Gtk.Image.from_icon_name ("tab-new", Gtk.IconSize.LARGE_TOOLBAR), _("Add a Server"));
359 var edit_user = new Gtk.MenuItem.with_label (_("Edit User Settings"));
360-
361+
362 var welcome = new Granite.Widgets.Welcome (_("Welcome to Cable"), _("Connect to the IRC world"));
363 welcome.append ("internet-web-browser", _("Channel"), _("Join a Channel"));
364 welcome.append ("tab-new", _("Server"), _("Add a Custom Server"));
365-
366+
367 var exp = new Gtk.ToolItem ();
368 exp.set_expand (true);
369-
370+
371 menu.append (edit_user);
372-
373+
374 toolbar.insert (join_channel, -1);
375 toolbar.insert (add_server, -1);
376 toolbar.insert (exp, -1);
377 toolbar.insert (create_appmenu (menu), -1);
378-
379+
380 main.pack_start (toolbar, false);
381 main.pack_start (paned);
382-
383+
384 paned.pack1 (servers, false, true);
385 paned.pack2 (display_box, true, true);
386-
387+
388 display_box.add (welcome);
389-
390+
391 window.set_application (this);
392 window.title = "Cable";
393 window.icon_name = "applications-chat";
394@@ -83,9 +83,9 @@
395 window.window_position = Gtk.WindowPosition.CENTER;
396 window.add (main);
397 window.show_all ();
398-
399+
400 window.show_all ();
401-
402+
403 welcome.activated.connect ((index) => {
404 if (index == 0) {
405 var dialog = get_join_dialog ();
406@@ -124,10 +124,10 @@
407 display_box.show_all ();
408 }
409 });
410-
411+
412 /*initial setup*/
413 var settings = Cable.Settings.get_default ();
414-
415+
416 //configuration incomplete
417 if (settings.real_name == "" || settings.nick == "") {
418 var settings_dialog = new Widgets.SettingsDialog ();
419@@ -135,57 +135,57 @@
420 settings_dialog.show_all ();
421 settings_dialog.run ();
422 }
423-
424+
425 //we got something to do
426 if (settings.favorites.length > 0) {
427-
428+
429 }
430 }
431-
432+
433 public Gtk.Dialog get_join_dialog ()
434 {
435 var dialog = new Gtk.Dialog ();
436 dialog.modal = true;
437-
438+
439 var box = new Gtk.Grid ();
440 box.margin = 12;
441 box.column_spacing = 6;
442 box.row_spacing = 6;
443-
444+
445 var entry = new Gtk.Entry ();
446 entry.secondary_icon_name = "edit-redo-symbolic";
447-
448+
449 var list = Widgets.Server.get_server_list ();
450-
451+
452 box.attach (new Gtk.Label (_("Server")), 0, 0, 1, 1);
453 box.attach (list, 1, 0, 1, 1);
454 box.attach (new Gtk.Label (_("Join Channel") + " #"), 0, 1, 1, 1);
455 box.attach (entry, 1, 1, 1, 1);
456 box.margin = 6;
457-
458+
459 entry.icon_release.connect (() => entry.activate ());
460 entry.activate.connect (() => {
461 foreach (var server in servers.root.children) {
462 if (server is Widgets.Server && (server as Widgets.Server).uri == list.active_id) {
463 (server as Widgets.Server).join_channel ("#"+entry.text);
464-
465+
466 dialog.destroy ();
467 return;
468 }
469 }
470-
471+
472 servers.root.add (new Widgets.Server (this, list.get_active_text (), list.active_id, "#"+entry.text));
473 dialog.destroy ();
474 });
475-
476+
477 (dialog.get_content_area () as Gtk.Container).add (box);
478 dialog.title = _("Join Channel");
479-
480+
481 entry.grab_focus ();
482-
483+
484 return dialog;
485 }
486-
487+
488 public override void activate ()
489 {
490 build ();
491@@ -196,8 +196,8 @@
492 public static int main (string [] args)
493 {
494 Gtk.init (ref args);
495-
496+
497 var cable = new Cable.App ();
498-
499+
500 return cable.run (args);
501 }
502
503=== modified file 'src/Global.vala'
504--- src/Global.vala 2012-08-22 15:00:43 +0000
505+++ src/Global.vala 2013-05-17 01:15:34 +0000
506@@ -5,18 +5,18 @@
507 get;
508 set;
509 }
510-
511+
512 Global ()
513 {
514-
515+
516 }
517-
518+
519 static Global? instance;
520 public static Global get_default ()
521 {
522 if (instance == null)
523 instance = new Global ();
524-
525+
526 return instance;
527 }
528 }
529
530=== modified file 'src/Widgets/Room.vala'
531--- src/Widgets/Room.vala 2012-10-25 19:43:33 +0000
532+++ src/Widgets/Room.vala 2013-05-17 01:15:34 +0000
533@@ -7,31 +7,31 @@
534 VOICED,
535 REGULAR
536 }
537-
538+
539 public enum MessageType
540 {
541 NORMAL,
542 ENTER,
543 LEAVE
544 }
545-
546+
547 public class Room : Granite.Widgets.SourceList.Item
548 {
549 Granite.Widgets.SourceList.ExpandableItem operators;
550 Granite.Widgets.SourceList.ExpandableItem voiced;
551 Granite.Widgets.SourceList.ExpandableItem regular;
552-
553+
554 Granite.Widgets.SourceList users;
555 Gtk.TreeView chat;
556 Gtk.ScrolledWindow left_scrolled;
557 public Gtk.Box room;
558-
559+
560 public signal void send_message (string message);
561-
562+
563 public Room (string channel)
564 {
565 name = channel;
566-
567+
568 room = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
569 var paned = new Gtk.Paned (Gtk.Orientation.HORIZONTAL);
570 var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
571@@ -45,18 +45,18 @@
572 left_scrolled = new Gtk.ScrolledWindow (null, null);
573 var right_scrolled = new Gtk.ScrolledWindow (null, null);
574 var user = new Gtk.Label ("<span color='#999'>"+Global.get_default ().user_nick+"</span>");
575-
576+
577 var left = new Gtk.CellRendererText ();
578 left.xalign = 1.0f;
579 left.width = 90;
580 left.font_desc = Pango.FontDescription.from_string (
581 new GLib.Settings ("org.gnome.desktop.interface").get_string ("monospace-font-name"));
582-
583+
584 var right = new Gtk.CellRendererText ();
585 right.wrap_mode = Pango.WrapMode.WORD_CHAR;
586 right.wrap_width = -1;
587 right.font_desc = left.font_desc;
588-
589+
590 chat.enable_grid_lines = Gtk.TreeViewGridLines.VERTICAL;
591 chat.headers_visible = false;
592 chat.insert_column_with_attributes (-1, null, left, "markup", 0);
593@@ -69,23 +69,23 @@
594 }", -1);
595 } catch (Error e) { warning (e.message); }
596 chat.get_style_context ().add_provider (css, 40000);
597-
598+
599 label.halign = Gtk.Align.START;
600-
601+
602 topic_item.add (label);
603 topic_item.set_expand (true);
604 topic.insert (topic_item, -1);
605 topic.get_style_context ().add_class ("seconday-toolbar");
606-
607+
608 operators = new Granite.Widgets.SourceList.ExpandableItem (_("Operators"));
609 voiced = new Granite.Widgets.SourceList.ExpandableItem ("Voiced");
610 regular = new Granite.Widgets.SourceList.ExpandableItem ("Regular");
611 users.root.add (operators);
612 users.root.add (voiced);
613 users.root.add (regular);
614-
615+
616 paned.get_style_context ().add_class ("sidebar-pane-separator");
617-
618+
619 css = new Gtk.CssProvider ();
620 try {
621 css.load_from_data ("*{
622@@ -93,18 +93,18 @@
623 }", -1);
624 } catch (Error e) { warning (e.message); }
625 users.get_style_context ().add_provider (css, 40000);
626-
627+
628 users.hscrollbar_policy = Gtk.PolicyType.NEVER;
629 users.width_request = 150;
630-
631+
632 paned.pack1 (box, true, false);
633 paned.pack2 (right_scrolled, false, false);
634-
635+
636 user.width_request = 99;
637 user.margin_right = 5;
638 user.xalign = 1.0f;
639 user.use_markup = true;
640-
641+
642 css = new Gtk.CssProvider ();
643 try {
644 css.load_from_data ("*{
645@@ -120,24 +120,24 @@
646 }", -1);
647 } catch (Error e) { warning (e.message); }
648 entry.get_style_context ().add_provider (css, 40000);
649-
650+
651 bottom.pack_start (user, false);
652 bottom.pack_start (entry);
653-
654+
655 left_scrolled.add (chat);
656-
657+
658 box.pack_start (left_scrolled);
659 box.pack_start (bottom, false);
660-
661+
662 room.pack_start (topic, false);
663 room.pack_start (paned);
664-
665+
666 entry.activate.connect (() => {
667 send_message (entry.text);
668- message ("tom95", entry.text);
669+ message (Global.get_default ().user_nick, entry.text);
670 entry.text = "";
671 });
672-
673+
674 bottom.draw.connect ((cr) => {
675 var grad = new Cairo.Pattern.linear (0, 0, 0, bottom.get_allocated_height () - 4);
676 grad.add_color_stop_rgb (0.0, 0.9, 0.9, 0.9);
677@@ -145,18 +145,18 @@
678 cr.rectangle (0, 0, bottom.get_allocated_width (), bottom.get_allocated_height ());
679 cr.set_source (grad);
680 cr.fill ();
681-
682+
683 cr.move_to (0, 0);
684 cr.line_to (room.get_allocated_width (), 0);
685 cr.close_path ();
686 cr.set_source_rgba (0.1, 0.1, 0.1, 1.0);
687 cr.set_line_width (1);
688 cr.stroke ();
689-
690+
691 return false;
692 });
693 }
694-
695+
696 public void add_user (string name, UserType type)
697 {
698 if (type == UserType.OPERATOR)
699@@ -165,10 +165,10 @@
700 voiced.add (new Granite.Widgets.SourceList.Item (name));
701 else
702 regular.add (new Granite.Widgets.SourceList.Item (name));
703-
704+
705 message (name, "", MessageType.ENTER);
706 }
707-
708+
709 public void remove_user (string name)
710 {
711 Granite.Widgets.SourceList.ExpandableItem[] lists = {voiced, operators, regular};
712@@ -176,36 +176,36 @@
713 foreach (var child in list.children) {
714 if (child.name == name) {
715 list.remove (child);
716-
717+
718 message (child.name, "", MessageType.LEAVE);
719-
720+
721 return;
722 }
723-
724+
725 return;
726 }
727 }
728 }
729-
730+
731 public void message (owned string from, string message, MessageType type=MessageType.NORMAL)
732 {
733 bool do_scroll = left_scrolled.vadjustment.value + 10 > left_scrolled.vadjustment.upper;
734-
735+
736 Gtk.TreeIter iter;
737 (chat.model as Gtk.ListStore).append (out iter);
738-
739+
740 if (type == MessageType.NORMAL) {
741-
742+
743 if (from == Global.get_default ().user_nick)
744 from = "<span color='#999'>"+from+"</span>";
745 else if (message.index_of (Global.get_default ().user_nick) != -1)
746 from = "<span color='#a00'>"+from+"</span>";
747-
748+
749 (chat.model as Gtk.ListStore).set (iter, 0, from, 1, message);
750 } else
751- (chat.model as Gtk.ListStore).set (iter, 0, "",
752+ (chat.model as Gtk.ListStore).set (iter, 0, "",
753 1, "<span color='#999'>%s has %s the room.</span>".printf (from, type == MessageType.ENTER ? "entered" : "left"));
754-
755+
756 Timeout.add (10, () => {
757 if (do_scroll)
758 left_scrolled.vadjustment.value = left_scrolled.vadjustment.upper;
759
760=== modified file 'src/Widgets/Server.vala'
761--- src/Widgets/Server.vala 2012-10-25 19:48:49 +0000
762+++ src/Widgets/Server.vala 2013-05-17 01:15:34 +0000
763@@ -8,29 +8,34 @@
764 "Freenode", " irc.freenode.net",
765 "GimpNET", "irc.gimp.org"
766 };
767-
768- Backend.Server server;
769+
770+ doodleIRC.DoodleIRCServer server;
771 App app;
772-
773+
774 public string uri;
775-
776+
777 public Server (App _app, string _name, string _uri, string? channel = null)
778 {
779 var settings = Settings.get_default ();
780 name = _name;
781 app = _app;
782 uri = _uri;
783-
784- Backend.User user = Backend.User () {
785+
786+ doodleIRC.User user = doodleIRC.User () {
787 realname = settings.real_name,
788 hostname = settings.nick,
789 username = settings.nick,
790 servername = uri
791 };
792- server = new Backend.Server ("irc.freenode.net", user, settings.nick);
793+ server = new doodleIRC.DoodleIRCServer ("irc.freenode.net", user, settings.nick);
794 Global.get_default ().user_nick = settings.nick; //TODO use fallback nicks
795-
796- server.connect ();
797+
798+ try {
799+ server.connect ();
800+ } catch (Error e) {
801+ //Needs Fixing
802+ Gtk.main_quit ();
803+ }
804 server.on_message.connect ((sender, chan, msg) => {
805 foreach (var room in children) {
806 if ((room as Room).name == chan) {
807@@ -38,50 +43,50 @@
808 return;
809 }
810 }
811-
812+
813 critical ("Channel '%s' has not been opened", chan);
814- });
815-
816+ });
817+
818 if (channel != null)
819 join_channel (channel);
820 }
821-
822+
823 public void join_channel (string channel)
824 {
825 var room = new Room (channel);
826 add (room);
827 expand_all ();
828-
829+
830 room.send_message.connect ((msg) => server.write (room.name, msg));
831 server.join_chan (channel);
832-
833+
834 app.servers.selected = room;
835 }
836-
837+
838 //builds up a ComboBox offering some default and your custom servers
839 public static Gtk.ComboBoxText get_server_list ()
840 {
841 var box = new Gtk.ComboBoxText ();
842-
843+
844 //add the default ones
845 for (var i = 0; i < DEFAULT_SERVERS.length; i += 2) {
846 box.append (DEFAULT_SERVERS[i + 1], DEFAULT_SERVERS[i]);
847 }
848-
849+
850 //add the custom ones
851 foreach (var server in Settings.get_default ().servers) {
852 if (server == "")
853 continue;
854-
855+
856 var details = server.split (":");
857 box.append (details[1], details[0]);
858 }
859-
860+
861 box.active = 0;
862-
863+
864 return box;
865 }
866-
867+
868 public static Gtk.Dialog get_add_dialog ()
869 {
870 var dialog = new Gtk.Dialog.with_buttons (_("Add Server"), null, Gtk.DialogFlags.MODAL);
871@@ -89,39 +94,38 @@
872 var name = new Gtk.Entry ();
873 var url = new Gtk.Entry ();
874 var add = new Gtk.Button.with_label (_("Add Server"));
875-
876+
877 name.placeholder_text = "Server";
878 url.placeholder_text = "irc.server.net";
879-
880 grid.margin = 12;
881 grid.column_spacing = 6;
882 grid.row_spacing = 6;
883-
884+
885 grid.attach (new Gtk.Label (_("Server Name:")), 0, 0, 1, 1);
886 grid.attach (name, 1, 0, 1, 1);
887 grid.attach (new Gtk.Label (_("Server URL:")), 0, 1, 1, 1);
888 grid.attach (url, 1, 1, 1, 1);
889 grid.attach (add, 1, 2, 1, 1);
890-
891+
892 url.activate.connect (() => add.clicked ());
893-
894+
895 add.clicked.connect (() => {
896 var servers = Settings.get_default ().servers;
897 servers.resize (servers.length + 1);
898 servers[servers.length - 1] = name.text + ":" + url.text;
899 Settings.get_default ().servers = servers;
900-
901+
902 dialog.destroy ();
903 });
904-
905+
906 name.changed.connect (() => add.sensitive = name.text != "" && url.text != "");
907 url.changed.connect (() => add.sensitive = name.text != "" && url.text != "");
908-
909+
910 add.sensitive = false;
911-
912+
913 (dialog.get_content_area () as Gtk.Container).add (grid);
914-
915+
916 return dialog;
917 }
918 }
919-}
920+}
921\ No newline at end of file
922
923=== added file 'src/doodleIRC.vala'
924--- src/doodleIRC.vala 1970-01-01 00:00:00 +0000
925+++ src/doodleIRC.vala 2013-05-17 01:15:34 +0000
926@@ -0,0 +1,345 @@
927+// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
928+/***
929+ BEGIN LICENSE
930+
931+ Copyright (C) 2013 Akshay Shekher <voldyman666@gmail.com>
932+ This program is free software: you can redistribute it and/or modify it
933+ under the terms of the GNU Lesser General Public License version 3, as published
934+ by the Free Software Foundation.
935+
936+ This program is distributed in the hope that it will be useful, but
937+ WITHOUT ANY WARRANTY; without even the implied warranties of
938+ MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
939+ PURPOSE. See the GNU General Public License for more details.
940+
941+ You should have received a copy of the GNU General Public License along
942+ with this program. If not, see <http://www.gnu.org/licenses/>
943+
944+ END LICENSE
945+***/
946+
947+namespace doodleIRC {
948+
949+ public class DoodleIRCServer {
950+
951+ // Signals
952+ public signal void on_connect_complete ();
953+ public signal void on_message (string sender, string chan, string msg);
954+ public signal void on_action (string sender, string chan, string msg);
955+ public signal void on_notice (string notice);
956+ public signal void on_error (string error_msg);
957+ public signal void on_user_join (string chan, string nick);
958+ public signal void on_join_complete (string chan, string nick);
959+ public signal void on_user_quit (string chan, string nick, string msg);
960+ public signal void on_names_listed (string chan,string[] names);
961+
962+ public List<string> chans;
963+ string nick;
964+ bool away;
965+ string server_url;
966+ User user;
967+ SocketConnection connection;
968+ DataInputStream response;
969+ bool connected;
970+ List<string> to_send;
971+ Gee.HashMap<string, string> list_of_names;
972+
973+ public DoodleIRCServer (string url, User user,string nick) {
974+ this.server_url = url;
975+ this.user = user;
976+ this.nick = nick;
977+ away = false;
978+
979+ this.chans = new List<string> ();
980+ connected = false;
981+ to_send = new List<string> ();
982+
983+ list_of_names = new Gee.HashMap<string,string> ();
984+
985+ on_connect_complete.connect (() => {
986+ to_send.foreach ((cmd) => {
987+ print ("Sending "+cmd);
988+ raw_send (cmd);
989+ to_send.remove (cmd);
990+ });
991+ });
992+ }
993+
994+ ~DoodleIRCServer () {
995+ print ("Exiting");
996+ quit_server ("Client Quit");
997+ }
998+
999+ public async void connect (string server = "") {
1000+ try {
1001+ // Resolve hostname to IP address
1002+ var resolver = Resolver.get_default ();
1003+ var addresses = yield resolver.lookup_by_name_async (this.server_url, null);
1004+ var address = addresses.nth_data (0);
1005+ print ("Resolved %s to %s\n".printf (this.server_url, address.to_string ()));
1006+
1007+ // Connect
1008+ var client = new SocketClient ();
1009+ connection = yield client.connect_async (new InetSocketAddress (address, 6667));
1010+ print ("Connected to %s\n".printf (this.server_url));
1011+ this.connected = true;
1012+ //response stream
1013+ response = new DataInputStream (connection.input_stream);
1014+
1015+ // Send USER request
1016+ var message = "USER %s %s %s :%s\r\n".printf (user.username, user.hostname,
1017+ user.servername, user.realname);
1018+ raw_send (message);
1019+ print ("Wrote request USER\n");
1020+
1021+ // Send NICK request
1022+ message = "NICK %s\r\n".printf (nick);
1023+ raw_send (message);
1024+ print ("Wrote nick request\n");
1025+
1026+ wait.begin ();
1027+ } catch (Error e) {
1028+ error ("Could not connect: %s".printf (e.message));
1029+ }
1030+
1031+ }
1032+
1033+ public async void wait () {
1034+ try {
1035+ var line = yield response.read_line_async ();
1036+ parse_line (line);
1037+ } catch (Error e) {
1038+ print ("Error: %s\n".printf (e.message));
1039+ }
1040+
1041+ if (connected)
1042+ wait.begin ();
1043+ }
1044+
1045+ private void parse_line (string line) {
1046+ print (line + "\n");
1047+
1048+ if (line[0] != ':') {
1049+ process_named_server_message (line);
1050+ return;
1051+ }
1052+
1053+ if (line[0] == ':') {
1054+ if ((line.split (" ")[1][0]).isdigit ()) {
1055+ process_numeric_cmd (line);
1056+ } else {
1057+ process_named_message (line);
1058+ }
1059+ }
1060+ }
1061+
1062+ private void process_named_message (string line) {
1063+ string sender="", cmd="", chan="", msg="";
1064+ parse_named_msg (line, out sender,out cmd, out chan, out msg);
1065+
1066+ switch (cmd.up ()) {
1067+ case "PRIVMSG":
1068+ if (msg.split (" ")[0] == "\001ACTION") {
1069+ msg = msg.replace ("ACTION ", "");
1070+ msg = msg.replace ("\001", "");
1071+ on_action (sender, chan, msg);
1072+ break;
1073+ }
1074+
1075+ print ("Chan-> "+chan+"\nMSG-> "+msg+"\n");
1076+ on_message (sender, chan, msg);
1077+ break;
1078+
1079+ case "QUIT":
1080+ print (" %s has quit\n".printf (sender));
1081+ on_user_quit (chan, sender, msg);
1082+ break;
1083+
1084+ case "JOIN":
1085+ if (sender == nick) {
1086+ on_join_complete (chan, sender);
1087+ break;
1088+ }
1089+ print ("User has Joined");
1090+ on_user_join (chan, sender);
1091+ break;
1092+ }
1093+ }
1094+
1095+ private void process_named_server_message (string line) {
1096+ var cmd = line.split (" ")[0].strip ();
1097+ var msg = line.split (" :")[1].strip ();
1098+
1099+ switch (cmd.up ()) {
1100+ case "PING":
1101+ print ("pinged\n");
1102+ raw_send (line.replace ("PING","PONG"));
1103+ break;
1104+
1105+ case "NOTICE":
1106+ print ("Noice: "+msg+"\n");
1107+ on_notice (msg);
1108+ break;
1109+
1110+ case "ERROR":
1111+ print ("An Error Occured: %s\n".printf (msg));
1112+ on_error (msg);
1113+ break;
1114+ }
1115+ }
1116+
1117+ private void process_numeric_cmd (string line) {
1118+ var first_split = line.split (" ");
1119+ /* this might come handy in the future :) */
1120+ //var sender = first_split[0].strip ();
1121+ var cmd = first_split[1].strip ();
1122+ var msg = line.split (" :")[1].strip ();
1123+
1124+ /* more info about these commands can be found at the IRC RFC page */
1125+ switch (cmd) {
1126+ case "001":
1127+ on_connect_complete ();
1128+ break;
1129+
1130+ case "005":
1131+ // this.connect (msg);
1132+ break;
1133+
1134+ case "301":
1135+ print ("Away: "+msg);
1136+ break;
1137+
1138+ case "433": // nick name is use
1139+ change_nick (this.nick+"_");
1140+ rejoin_channels ();
1141+ break;
1142+
1143+ case "353": //RPL_NAMESLISTED
1144+ var chan = first_split[4];
1145+ if (list_of_names.has_key (chan)) {
1146+ var names = list_of_names.get (chan);
1147+ names = " " + msg;
1148+ list_of_names.set (chan, names);
1149+ } else {
1150+ list_of_names.set (chan, msg);
1151+ }
1152+
1153+ break;
1154+
1155+ case "366": //RPL_ENDOFNAMES
1156+ foreach (var channel in list_of_names.keys.to_array ()) {
1157+ on_names_listed (channel, list_of_names.get (channel).split (" "));
1158+ }
1159+
1160+ list_of_names.clear ();
1161+ break;
1162+ }
1163+ }
1164+
1165+ private void parse_named_msg (string line, out string sender,out string cmd,
1166+ out string chan, out string msg) {
1167+ // split the message from the info
1168+ var first_split = line.split (":");
1169+ var info = first_split[1];
1170+ // msg = join_str_ar (2, first_split.length, first_split);
1171+ msg = line.split (" :")[1];
1172+
1173+ // split the info to extract sender and chan
1174+ var second_split = info.split (" ");
1175+ cmd = second_split[1].strip ();
1176+ chan = second_split[2].strip ();
1177+ sender = second_split[0].strip ().split ("!")[0];
1178+ }
1179+
1180+ private void raw_send (string line) {
1181+ try {
1182+ connection.output_stream.write (line.data);
1183+ connection.output_stream.flush ();
1184+ } catch (Error e) {
1185+ error ("raw_send: %s".printf (e.message));
1186+ }
1187+ }
1188+
1189+ public void send (string cmd) {
1190+ if (connected)
1191+ raw_send (cmd);
1192+ else
1193+ to_send.append (cmd);
1194+ }
1195+
1196+ private void rejoin_channels () {
1197+ // Send JOIN request
1198+ foreach (string chan in chans) {
1199+ raw_send ("JOIN %s\r\n".printf (chan));
1200+ print ("Wrote request to join %s\n".printf (chan));
1201+ }
1202+ }
1203+
1204+ public void kick_user (string chan, string user, string reason) {
1205+ send ("KICK %s %s :%s\r\n".printf (chan, user, reason));
1206+ }
1207+
1208+ public void join_chan (string chan, string key="") {
1209+ send ("JOIN %s :%s\r\n".printf (chan, key));
1210+ chans.append (chan);
1211+ }
1212+
1213+ public void quit_server (string message) {
1214+ send ("QUIT :%s\r\n".printf (message));
1215+ }
1216+
1217+ public void leave_chan (string chan) {
1218+ send ("PART %s\r\n".printf (chan));
1219+ }
1220+
1221+ public void write (string chan, string msg) {
1222+ send ("PRIVMSG %s :%s\r\n".printf (chan, msg));
1223+ }
1224+
1225+ public void notice (string to, string text) {
1226+ send ("NOTICE %s :%s\r\n".printf (to, text));
1227+ }
1228+
1229+ public void get_names (string chan) {
1230+ send ("NAMES %s\r\n".printf (chan));
1231+ }
1232+
1233+ public void set_away (string reason) {
1234+ away = true;
1235+ send ("AWAY :%s\r\n".printf (reason));
1236+ }
1237+
1238+ public void set_back () {
1239+ away = false;
1240+ send ("AWAY \r\n");
1241+ }
1242+
1243+ public void toggle_away (string reason = "") {
1244+ if (this.away)
1245+ set_back ();
1246+ else
1247+ set_away (reason);
1248+ }
1249+
1250+ public void change_nick (string nick) {
1251+ this.nick = nick;
1252+ raw_send ("NICK %s\r\n".printf (this.nick));
1253+ }
1254+
1255+ public void write_action (string chan, string msg) {
1256+ write (chan, "\001ACTION %s\001\r\n".printf (msg));
1257+ }
1258+
1259+ public void disconnect () {
1260+ raw_send ("QUIT :bye");
1261+ connected = false;
1262+ }
1263+ }
1264+
1265+ public struct User {
1266+ public string username;
1267+ public string hostname;
1268+ public string servername;
1269+ public string realname;
1270+ }
1271+}

Subscribers

People subscribed via source and target branches

to all changes: