rapache-devel team mailing list archive
-
rapache-devel team
-
Mailing list archive
-
Message #00316
[Merge] lp:~octy92/rapache/tray_icon into lp:rapache
Alfred Maghi has proposed merging lp:~octy92/rapache/tray_icon into lp:rapache.
Requested reviews:
Rapache Developers (rapache-devel)
Related bugs:
#268403 Rapache tray icon
https://bugs.launchpad.net/bugs/268403
That branch has a tray icon: a click on the tray icon hides or shows the Rapache window.
Exiting the Rapache window destroy the tray icon has well.
--
https://code.launchpad.net/~octy92/rapache/tray_icon/+merge/25408
Your team Rapache Developers is requested to review the proposed merge of lp:~octy92/rapache/tray_icon into lp:rapache.
=== added file 'Glade/connect.'
--- Glade/connect. 1970-01-01 00:00:00 +0000
+++ Glade/connect. 2010-05-16 23:57:26 +0000
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Wed Sep 17 16:06:20 2008 -->
+<glade-interface>
+ <widget class="GtkDialog" id="dialog1">
+ <property name="border_width">5</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">2</property>
+ <child>
+ <widget class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Server</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Username</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label13">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Port (<i>default 22</i>)</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="spinbutton1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">0 0 100 1 10 10</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Password</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="button2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-connect</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
=== added file 'Glade/connect.glade'
--- Glade/connect.glade 1970-01-01 00:00:00 +0000
+++ Glade/connect.glade 2010-05-16 23:57:26 +0000
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Mon Sep 22 22:04:48 2008 -->
+<glade-interface>
+ <widget class="GtkDialog" id="dialog_connect">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Connection Details</property>
+ <property name="modal">True</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">4</property>
+ <child>
+ <widget class="GtkLabel" id="label13">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Port</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ <property name="x_padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_password">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="visibility">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Password</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_username">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="spinbutton_port">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">22 0 10000 1 10 10</property>
+ </widget>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Username</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ <property name="x_padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_server">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Server</property>
+ </widget>
+ <packing>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="button_cancel">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_button_cancel_clicked"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_connect">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-connect</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_button_connect_clicked"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
=== added file 'Glade/edit_connection.glade'
--- Glade/edit_connection.glade 1970-01-01 00:00:00 +0000
+++ Glade/edit_connection.glade 2010-05-16 23:57:26 +0000
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Thu Sep 11 16:22:57 2008 -->
+<glade-interface>
+ <widget class="GtkDialog" id="dialog1">
+ <property name="border_width">5</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">5</property>
+ <property name="n_columns">2</property>
+ <child>
+ <widget class="GtkEntry" id="entry3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Password</property>
+ </widget>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Username</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <child>
+ <widget class="GtkSpinButton" id="spinbutton1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">0 0 10000 1 10 10</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Port</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Server</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="button2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-close</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-connect</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
=== modified file 'Glade/main.glade'
--- Glade/main.glade 2008-09-15 04:55:10 +0000
+++ Glade/main.glade 2010-05-16 23:57:26 +0000
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.5 on Mon Sep 15 06:53:14 2008 -->
+<!--Generated with glade3 3.4.5 on Wed Sep 24 13:55:33 2008 -->
<glade-interface>
<widget class="GtkWindow" id="MainWindow">
- <property name="width_request">500</property>
+ <property name="width_request">700</property>
<property name="height_request">400</property>
<property name="visible">True</property>
<property name="title" translatable="yes">Rapache</property>
@@ -11,6 +11,7 @@
<signal name="destroy" handler="on_MainWindow_destroy"/>
<child>
<widget class="GtkVBox" id="vbox7">
+ <property name="width_request">700</property>
<property name="visible">True</property>
<child>
<widget class="GtkMenuBar" id="menubar1">
@@ -25,6 +26,7 @@
<property name="visible">True</property>
<child>
<widget class="GtkImageMenuItem" id="menuitem_connect">
+ <property name="visible">True</property>
<property name="sensitive">False</property>
<property name="label" translatable="yes">_Connect</property>
<property name="use_underline">True</property>
@@ -38,6 +40,7 @@
</child>
<child>
<widget class="GtkImageMenuItem" id="menuitem_disconnect">
+ <property name="visible">True</property>
<property name="sensitive">False</property>
<property name="label" translatable="yes">_Disconnect</property>
<property name="use_underline">True</property>
@@ -51,6 +54,7 @@
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
+ <property name="visible">True</property>
</widget>
</child>
<child>
@@ -93,6 +97,60 @@
</widget>
</child>
<child>
+ <widget class="GtkMenuItem" id="menuitem_ookmarks">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Bookmarks</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="menuitem_add_bookmark">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="label" translatable="yes">_Add to bookmarks</property>
+ <property name="use_underline">True</property>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image8">
+ <property name="visible">True</property>
+ <property name="stock">gtk-save</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menuitem_edit_bookmarks">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="label" translatable="yes">_Edit bookmark</property>
+ <property name="use_underline">True</property>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image9">
+ <property name="visible">True</property>
+ <property name="stock">gtk-edit</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menuitem_delete_bookmark">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="label" translatable="yes">_Remove from bookmarks</property>
+ <property name="use_underline">True</property>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image10">
+ <property name="visible">True</property>
+ <property name="stock">gtk-delete</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
<widget class="GtkMenuItem" id="toolsmenu">
<property name="visible">True</property>
<property name="label" translatable="yes">_Tools</property>
@@ -103,6 +161,7 @@
<child>
<widget class="GtkImageMenuItem" id="menuitem_start_apache">
<property name="visible">True</property>
+ <property name="sensitive">False</property>
<property name="label" translatable="yes">_Start Apache</property>
<property name="use_underline">True</property>
<signal name="activate" handler="please_restart"/>
@@ -116,6 +175,7 @@
<child>
<widget class="GtkImageMenuItem" id="menuitem_restart_apache">
<property name="visible">True</property>
+ <property name="sensitive">False</property>
<property name="label" translatable="yes">_Restart Apache</property>
<property name="use_underline">True</property>
<signal name="activate" handler="please_restart"/>
@@ -129,6 +189,7 @@
<child>
<widget class="GtkImageMenuItem" id="menuitem_stop_apache">
<property name="visible">True</property>
+ <property name="sensitive">False</property>
<property name="label" translatable="yes">_Stop Apache</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_menuitem_stop_apache_activate"/>
@@ -189,598 +250,749 @@
</packing>
</child>
<child>
- <widget class="GtkVBox" id="vbox1">
+ <widget class="GtkHPaned" id="hpaned1">
<property name="visible">True</property>
- <child>
- <widget class="GtkHBox" id="hbox9">
- <child>
- <widget class="GtkLabel" id="label9">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Server :</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="padding">8</property>
- </packing>
- </child>
- <child>
- <widget class="GtkComboBoxEntry" id="comboboxentry1">
- <property name="visible">True</property>
- <property name="items" translatable="yes">localhost</property>
- <child internal-child="entry">
- <widget class="GtkEntry" id="comboboxentry-entry1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkButton" id="button1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="label" translatable="yes">gtk-connect</property>
- <property name="use_stock">True</property>
- <property name="response_id">0</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="padding">8</property>
- <property name="position">2</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="padding">8</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHBox" id="restart_apache_notice">
- <child>
- <widget class="GtkVBox" id="vbox5">
- <property name="visible">True</property>
- <child>
- <widget class="GtkButton" id="restart_apache">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="label" translatable="yes">gtk-refresh</property>
- <property name="use_stock">True</property>
- <property name="response_id">0</property>
- <signal name="clicked" handler="please_restart"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="padding">7</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="padding">7</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Applied changes will not take effect until
-web server is restarted</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">True</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
- <property name="width_chars">0</property>
- </widget>
- <packing>
- <property name="padding">4</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkVBox" id="vbox6">
- <property name="visible">True</property>
- <property name="homogeneous">True</property>
- <child>
- <widget class="GtkButton" id="button_hide_warning">
+ <property name="can_focus">True</property>
+ <property name="position_set">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox9">
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment3">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Bookmarks</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">GTK_RELIEF_NONE</property>
- <property name="focus_on_click">False</property>
<property name="response_id">0</property>
- <signal name="clicked" handler="on_button_hide_warning_clicked"/>
<child>
- <widget class="GtkImage" id="image2">
+ <widget class="GtkImage" id="image6">
<property name="visible">True</property>
<property name="stock">gtk-close</property>
+ <property name="icon_size">1</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
+ <property name="position">2</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="padding">8</property>
- <property name="position">2</property>
+ <property name="padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="width_request">150</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+ <child>
+ <widget class="GtkTreeView" id="treeview_bookmarks">
+ <property name="width_request">150</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
</packing>
</child>
</widget>
<packing>
- <property name="expand">False</property>
- <property name="position">1</property>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
</packing>
</child>
<child>
- <widget class="GtkNotebook" id="notebook">
+ <widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
- <property name="can_focus">True</property>
<child>
- <widget class="GtkVBox" id="vbox2">
- <property name="visible">True</property>
+ <widget class="GtkHBox" id="restart_apache_notice">
<child>
- <widget class="GtkToolbar" id="toolbar6">
+ <widget class="GtkVBox" id="vbox5">
<property name="visible">True</property>
- <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
<child>
- <widget class="GtkToolButton" id="button_resolve_errors">
+ <widget class="GtkButton" id="restart_apache">
<property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="is_important">True</property>
- <property name="label" translatable="yes">Resolve Errors</property>
- <property name="stock_id">gtk-apply</property>
- <signal name="clicked" handler="on_button_resolve_errors_clicked"/>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-refresh</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="please_restart"/>
</widget>
<packing>
<property name="expand">False</property>
+ <property name="padding">7</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <child>
- <widget class="GtkViewport" id="viewport_errors">
- <property name="visible">True</property>
- <property name="resize_mode">GTK_RESIZE_QUEUE</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox3">
- <property name="visible">True</property>
- <child>
- <widget class="GtkImage" id="image5">
- <property name="visible">True</property>
- <property name="stock">gtk-dialog-warning</property>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label6">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Problems</property>
- </widget>
- <packing>
- <property name="padding">5</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="type">tab</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkVBox" id="vbox4">
- <property name="visible">True</property>
- <child>
- <widget class="GtkHBox" id="hbox4">
- <property name="visible">True</property>
- <child>
- <widget class="GtkToolbar" id="toolbar1">
- <property name="visible">True</property>
- <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
- <child>
- <widget class="GtkMenuToolButton" id="new_button">
- <property name="visible">True</property>
- <property name="is_important">True</property>
- <property name="use_underline">True</property>
- <property name="stock_id">gtk-new</property>
- <signal name="clicked" handler="new_button_clicked"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="edit_button">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="is_important">True</property>
- <property name="use_underline">True</property>
- <property name="stock_id">gtk-edit</property>
- <signal name="clicked" handler="edit_button_clicked"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="delete_button">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="is_important">True</property>
- <property name="stock_id">gtk-delete</property>
- <signal name="clicked" handler="on_delete"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkSeparatorToolItem" id="toolbutton1">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="browse_button">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="is_important">True</property>
- <property name="label" translatable="yes">Browse Files</property>
- <property name="stock_id">gtk-open</property>
- <signal name="clicked" handler="browse_button_clicked"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="surf_this_button">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="is_important">True</property>
- <property name="label" translatable="yes">Open Site</property>
- <property name="icon_name">applications-internet</property>
- <signal name="clicked" handler="surf_this_button_clicked"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- </widget>
- </child>
- <child>
- <placeholder/>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkScrolledWindow" id="vhosts_scroll_box">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <child>
- <widget class="GtkViewport" id="viewport1">
- <property name="visible">True</property>
- <property name="resize_mode">GTK_RESIZE_QUEUE</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <child>
- <widget class="GtkVBox" id="vhost_container">
- <property name="visible">True</property>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <child>
- <widget class="GtkImage" id="image3">
- <property name="visible">True</property>
- <property name="icon_name">applications-internet</property>
- </widget>
+ <property name="padding">7</property>
+ </packing>
</child>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
- <property name="label" translatable="yes">Web Sites</property>
+ <property name="label" translatable="yes">Applied changes will not take effect until
+web server is restarted</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">True</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
+ <property name="width_chars">0</property>
</widget>
<packing>
- <property name="padding">5</property>
+ <property name="padding">4</property>
<property name="position">1</property>
</packing>
</child>
+ <child>
+ <widget class="GtkVBox" id="vbox6">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <widget class="GtkButton" id="button_hide_warning">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">GTK_RELIEF_NONE</property>
+ <property name="focus_on_click">False</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_button_hide_warning_clicked"/>
+ <child>
+ <widget class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="stock">gtk-close</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">8</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
</widget>
<packing>
- <property name="type">tab</property>
+ <property name="expand">False</property>
<property name="position">1</property>
- <property name="tab_fill">False</property>
</packing>
</child>
<child>
- <widget class="GtkVBox" id="vbox3">
+ <widget class="GtkHBox" id="hbox9">
<property name="visible">True</property>
<child>
- <widget class="GtkHBox" id="hbox5">
+ <widget class="GtkLabel" id="label9">
<property name="visible">True</property>
- <child>
- <widget class="GtkToolbar" id="toolbar2">
- <property name="visible">True</property>
- <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
- <child>
- <widget class="GtkToolButton" id="edit_module_button">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="is_important">True</property>
- <property name="use_underline">True</property>
- <property name="stock_id">gtk-edit</property>
- <signal name="clicked" handler="edit_module_button_clicked"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="open_doc_button">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="is_important">True</property>
- <property name="label" translatable="yes">Documentation</property>
- <property name="stock_id">gtk-help</property>
- <signal name="clicked" handler="open_doc_button_clicked"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- </widget>
- </child>
- <child>
- <widget class="GtkToolbar" id="toolbar3">
- <property name="visible">True</property>
- <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
- <property name="show_arrow">False</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="pack_type">GTK_PACK_END</property>
- <property name="position">1</property>
- </packing>
- </child>
+ <property name="label" translatable="yes">Server :</property>
</widget>
<packing>
<property name="expand">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkScrolledWindow" id="modules_scroll_box">
+ <property name="fill">False</property>
+ <property name="padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBoxEntry" id="comboboxentry_server">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes"></property>
+ <child internal-child="entry">
+ <widget class="GtkEntry" id="comboboxentry-entry1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkProgressBar" id="progressbar">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="show_text">True</property>
+ <property name="pulse_step">0.050000000000000003</property>
+ <property name="text" translatable="yes"> </property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_connection">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <child>
- <widget class="GtkViewport" id="viewport2">
- <property name="visible">True</property>
- <property name="resize_mode">GTK_RESIZE_QUEUE</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <child>
- <widget class="GtkVBox" id="modules_container">
- <property name="visible">True</property>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-connect</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_button_connection_clicked"/>
</widget>
<packing>
- <property name="position">1</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">8</property>
+ <property name="position">3</property>
</packing>
</child>
</widget>
<packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">8</property>
<property name="position">1</property>
</packing>
</child>
<child>
- <widget class="GtkHBox" id="hbox2">
- <property name="visible">True</property>
- <child>
- <widget class="GtkImage" id="image4">
- <property name="visible">True</property>
- <property name="pixbuf">modules.png</property>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Modules</property>
- </widget>
- <packing>
- <property name="padding">5</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="type">tab</property>
- <property name="position">2</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox8">
- <property name="visible">True</property>
- <child>
- <widget class="GtkVBox" id="vbox8">
+ <widget class="GtkNotebook" id="notebook">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<child>
- <widget class="GtkHBox" id="hbox10">
+ <widget class="GtkToolbar" id="toolbar6">
<property name="visible">True</property>
- <child>
- <widget class="GtkLabel" id="label7">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Log File</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkComboBox" id="combobox_log">
- <property name="visible">True</property>
- <property name="items" translatable="yes"></property>
- </widget>
- <packing>
- <property name="padding">8</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkButton" id="button_open_log">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="label" translatable="yes">gtk-open</property>
- <property name="use_stock">True</property>
- <property name="response_id">0</property>
- <signal name="clicked" handler="on_button_open_log_clicked"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
+ <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
+ <child>
+ <widget class="GtkToolButton" id="button_resolve_errors">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">Resolve Errors</property>
+ <property name="stock_id">gtk-apply</property>
+ <signal name="clicked" handler="on_button_resolve_errors_clicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="padding">8</property>
</packing>
</child>
<child>
- <widget class="GtkScrolledWindow" id="scroll_window_log">
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+ <child>
+ <widget class="GtkViewport" id="viewport_errors">
+ <property name="visible">True</property>
+ <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImage" id="image5">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-warning</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Problems</property>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox4">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="hbox4">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkToolbar" id="toolbar1">
+ <property name="visible">True</property>
+ <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
+ <child>
+ <widget class="GtkMenuToolButton" id="new_button">
+ <property name="visible">True</property>
+ <property name="is_important">True</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-new</property>
+ <signal name="clicked" handler="new_button_clicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="edit_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="is_important">True</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-edit</property>
+ <signal name="clicked" handler="edit_button_clicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="delete_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="is_important">True</property>
+ <property name="stock_id">gtk-delete</property>
+ <signal name="clicked" handler="on_delete"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="toolbutton1">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="browse_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">Browse Files</property>
+ <property name="stock_id">gtk-open</property>
+ <signal name="clicked" handler="browse_button_clicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="surf_this_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">Open Site</property>
+ <property name="icon_name">applications-internet</property>
+ <signal name="clicked" handler="surf_this_button_clicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
<child>
<placeholder/>
</child>
</widget>
<packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox11">
- <property name="visible">True</property>
- <child>
- <widget class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <child>
- <widget class="GtkLabel" id="label_log_path">
- <property name="visible">True</property>
- <property name="use_markup">True</property>
- <property name="selectable">True</property>
- </widget>
- </child>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="vhosts_scroll_box">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <widget class="GtkViewport" id="viewport1">
+ <property name="visible">True</property>
+ <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <child>
+ <widget class="GtkVBox" id="vhost_container">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="icon_name">applications-internet</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Web Sites</property>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="hbox5">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkToolbar" id="toolbar2">
+ <property name="visible">True</property>
+ <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
+ <child>
+ <widget class="GtkToolButton" id="edit_module_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="is_important">True</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-edit</property>
+ <signal name="clicked" handler="edit_module_button_clicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="open_doc_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">Documentation</property>
+ <property name="stock_id">gtk-help</property>
+ <signal name="clicked" handler="open_doc_button_clicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkToolbar" id="toolbar3">
+ <property name="visible">True</property>
+ <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
+ <property name="show_arrow">False</property>
</widget>
<packing>
<property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label4">
- <property name="visible">True</property>
- </widget>
- <packing>
+ <property name="pack_type">GTK_PACK_END</property>
<property name="position">1</property>
</packing>
</child>
- <child>
- <widget class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <child>
- <widget class="GtkLinkButton" id="linkbutton_documentation">
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="modules_scroll_box">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <widget class="GtkViewport" id="viewport2">
+ <property name="visible">True</property>
+ <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <child>
+ <widget class="GtkVBox" id="modules_container">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox6">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImage" id="image4">
+ <property name="visible">True</property>
+ <property name="pixbuf">modules.png</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Modules</property>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox8">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox8">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">3</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_open_log">
+ <property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <property name="label" translatable="yes">virtualhost documentation</property>
- <property name="relief">GTK_RELIEF_NONE</property>
- <property name="focus_on_click">False</property>
+ <property name="label" translatable="yes">gtk-open</property>
+ <property name="use_stock">True</property>
<property name="response_id">0</property>
- <property name="uri">http://httpd.apache.org/docs/2.0/mod/core.html#virtualhost</property>
- </widget>
+ <signal name="clicked" handler="on_button_open_log_clicked"/>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ <property name="x_padding">8</property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="spinbutton_log_limit">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">100 10 100000 10 100 10</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ <property name="x_padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="tooltip_text">Limit the log file to last N number of lines</property>
+ <property name="label" translatable="yes">Line Limit</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="combobox_log">
+ <property name="visible">True</property>
+ <property name="row_span_column">0</property>
+ <property name="items" translatable="yes"></property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ <property name="x_padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Log File</property>
+ </widget>
+ <packing>
+ <property name="x_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scroll_window_log">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox11">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <child>
+ <widget class="GtkLabel" id="label_log_path">
+ <property name="visible">True</property>
+ <property name="use_markup">True</property>
+ <property name="selectable">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <child>
+ <widget class="GtkLinkButton" id="linkbutton_documentation">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">virtualhost documentation</property>
+ <property name="relief">GTK_RELIEF_NONE</property>
+ <property name="focus_on_click">False</property>
+ <property name="response_id">0</property>
+ <property name="uri">http://httpd.apache.org/docs/2.0/mod/core.html#virtualhost</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">8</property>
+ <property name="position">2</property>
+ </packing>
</child>
</widget>
<packing>
@@ -792,86 +1004,98 @@
</child>
</widget>
<packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
<property name="padding">8</property>
- <property name="position">2</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">8</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox7">
- <property name="visible">True</property>
- <child>
- <widget class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="stock">gtk-justify-fill</property>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label10">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Log Files</property>
- </widget>
- <packing>
- <property name="padding">5</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="type">tab</property>
- <property name="position">3</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox7">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-justify-fill</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Log Files</property>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox12">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImage" id="image_apache_status">
+ <property name="visible">True</property>
+ <property name="stock">gtk-media-stop</property>
+ <property name="icon_size">1</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label_server_status">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label11">
+ <property name="visible">True</property>
</widget>
<packing>
<property name="position">2</property>
</packing>
</child>
<child>
- <widget class="GtkHBox" id="hbox6">
- <property name="visible">True</property>
- <child>
- <widget class="GtkImage" id="image_apache_status">
- <property name="visible">True</property>
- <property name="stock">gtk-no</property>
- <property name="icon_size">1</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="padding">2</property>
- </packing>
- </child>
- <child>
- <widget class="GtkStatusbar" id="statusbar_server_status">
- <property name="visible">True</property>
- <property name="spacing">2</property>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="position">3</property>
- </packing>
+ <placeholder/>
</child>
</widget>
<packing>
- <property name="position">1</property>
+ <property name="expand">False</property>
+ <property name="padding">2</property>
+ <property name="position">2</property>
</packing>
</child>
</widget>
=== added file 'Glade/progress.glade'
--- Glade/progress.glade 1970-01-01 00:00:00 +0000
+++ Glade/progress.glade 2010-05-16 23:57:26 +0000
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Wed Sep 17 10:13:51 2008 -->
+<glade-interface>
+ <widget class="GtkDialog" id="dialog_progress">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Communicating with Server</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Please standby....</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkProgressBar" id="progressbar1">
+ <property name="visible">True</property>
+ <property name="activity_mode">True</property>
+ <property name="show_text">True</property>
+ <property name="text" translatable="yes"></property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkExpander" id="expander1">
+ <property name="can_focus">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">expander</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">8</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="button_cancel">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_button_cancel_clicked"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
=== modified file 'RapacheCore/Apache.py'
--- RapacheCore/Apache.py 2008-09-15 04:16:47 +0000
+++ RapacheCore/Apache.py 2010-05-16 23:57:26 +0000
@@ -4,31 +4,225 @@
import urllib2
from RapacheCore import Shell
+from RapacheCore import ShellSSH
+from RapacheCore import Configuration
+from RapacheCore.VirtualHost import *
+from RapacheCore.Module import *
+from RapacheCore.ApacheError import *
class Apache2():
-
- def __init__(self):
- self.server = "localhost"
+ def __init__(self, server):
+ self.server = server
+
+ self.__virtual_hosts = None
+ self.__modules = None
+ self.__errors = None
+ self.__logs = None
+
+ self.__module_descriptions = get_module_descriptions()
+
+ def count(self):
+ total = 0
+ if self.__virtual_hosts: total = total + len(self.__virtual_hosts)
+ if self.__modules: total = total + len(self.__modules)
+ if self.__errors: total = total + len(self.__errors)
+ return total
+
+ def __get_enabled_virtual_hosts(self):
+ print "__get_enabled_virtual_hosts"
+ dir_enabled_all = self.server.command.listdir( Configuration.SITES_ENABLED_DIR )
+ dir_enabled_all = [x for x in dir_enabled_all if not re.match( "(.*[~]\s*$)|(.*.swp$)", x )]
+
+ # get list of files in available that are enabled
+ dir_enabled = []
+ for fname in dir_enabled_all:
+ flink = self.server.command.readlink( os.path.join(Configuration.SITES_ENABLED_DIR, fname) )
+ if flink:
+ flink = os.path.join(os.path.dirname( Configuration.SITES_ENABLED_DIR +"/" ), flink)
+ # please note debian features a nice set of
+ # mixed absolute and relative links. FREAKS !
+ # the added "/" is also necessary
+ flink = os.path.normpath(flink)
+ dir_enabled.append(flink)
+ return dir_enabled
+
+ def get_virtual_hosts(self, ReloadChange=False, Force=False):
+
+ # force caching by default
+ if self.__virtual_hosts and not Force:
+ print "Loading cached hosts"
+ if ReloadChange:
+ dir_enabled = None
+ for key in self.__virtual_hosts:
+ host = self.__virtual_hosts[key]
+ if host.changed:
+ print key
+ # Need to reload this module and check enabled status
+ if not dir_enabled: dir_enabled = self.__get_enabled_virtual_hosts()
+ host.load()
+ host.enabled = host.get_source_filename() in dir_enabled
+
+ return self.__virtual_hosts
+
+ self.__virtual_hosts = {}
+
+ dir_available = self.server.command.listdir( Configuration.SITES_AVAILABLE_DIR )
+ dir_available = [x for x in dir_available if not re.match( "(.*[~]\s*$)|(.*.swp$)", x )]
+
+ dir_enabled = self.__get_enabled_virtual_hosts()
+
+ for fname in dir_available :
+ enabled = os.path.join(Configuration.SITES_AVAILABLE_DIR, fname) in dir_enabled
+ site = VirtualHostModel( fname, self, enabled )
+ if not site.is_new:
+ self.__virtual_hosts[ fname ] = site
+
+ return self.__virtual_hosts
+
+
+
+ def __get_enabled_modules(self):
+ # get list of files in available that are enabled
+ dir_enabled = []
+ for fname in self.server.command.listdir( Configuration.MODS_ENABLED_DIR ):
+
+ if fname.endswith( ".load"):
+
+ flink = self.server.command.readlink( os.path.join(Configuration.MODS_ENABLED_DIR, fname) )
+ flink = os.path.join(os.path.dirname( Configuration.MODS_ENABLED_DIR +"/" ), flink)
+ # please note debian brilliantly features a nice set of
+ # mixed absolute and relative links. FREAKS !
+ # the added "/" is also necessary
+ flink = os.path.normpath( flink )
+
+ dir_enabled.append( flink )
+
+ return dir_enabled
+
+ def get_modules(self, ReloadChanges=False, Force=False):
+
+ # force caching by default
+ if self.__modules and not Force:
+ if ReloadChanges:
+ dir_enabled = None
+ # check modules that have been saved and need updating...
+ for key in self.__modules:
+ mod = self.__modules[key]
+ if mod.changed:
+ # Need to reload this module and check enabled status
+ if not dir_enabled: dir_enabled = self.__get_enabled_modules()
+ mod.load()
+ mod.data['enabled'] = os.path.join(Configuration.MODS_AVAILABLE_DIR, key + ".load") in dir_enabled
+ return self.__modules
+
+ self.__modules = {}
+
+ dir_available = self.server.command.listdir( Configuration.MODS_AVAILABLE_DIR )
+ dir_available = [x for x in dir_available if not re.match( "(.*[~]\s*$)|(.*.swp$)", x ) ]
+
+ dir_enabled = self.__get_enabled_modules()
+
+ for fname in dir_available :
+ tokens = os.path.splitext( fname )
+ if tokens[1] == '.load':
+ description = None
+
+ # find a description
+ if self.__module_descriptions.has_key(tokens[0]):
+ description = self.__module_descriptions[tokens[0]]
+ elif self.__module_descriptions.has_key("mod_" + tokens[0]):
+ description = self.__module_descriptions["mod_" + tokens[0]]
+
+ enabled = os.path.join(Configuration.MODS_AVAILABLE_DIR, fname) in dir_enabled
+ mod = ModuleModel( tokens[0], self, enabled)
+ mod.data[ 'description' ] = description
+ try:
+ mod.load( )
+ except "VhostUnparsable":
+ pass
+
+ self.__modules[ tokens[0] ] = mod
+ mod = None
+ return self.__modules
+
+ def get_logs(self, Force = False):
+
+ # force caching by default
+ if self.__logs and not Force:
+ return self.__logs
+
+ self.__logs = self.server.command.listdir( Configuration.LOG_PATH )
+ self.__logs = [x for x in self.__logs if x.endswith(".log") ]
+ return self.__logs
+
+ def get_errors(self, Force = False):
+
+ if self.__errors and not Force:
+ return self.__errors
+
+ self.__errors = []
+
+ # only do this if we have sudo auth
+ if not self.server.command.is_auth_needed():
+ result, text = self.test_config()
+ if not result:
+ self.__errors.append( ApacheConfigError( text ) )
+
+ # Check for ssl module and vhost have specifed ports
+ if self.get_modules()["ssl"].data['enabled']:
+ for key in self.get_virtual_hosts():
+ vhost = self.get_virtual_hosts()[key]
+ if vhost.enabled and not vhost.has_port():
+ self.__errors.append( ApachePortRequiredVhostError( vhost ) )
+
+ # Check unnormalised vhosts
+ for key in self.get_virtual_hosts():
+ vhost = self.get_virtual_hosts()[key]
+ if vhost.is_denormalized_vhost():
+ self.__errors.append( ApacheDenomalisedVhostError( vhost ) )
+
+ print "Errors - ", len(self.__errors)
+
+ return self.__errors
+
+ def get_fixable_error_count(self):
+ count = 0
+ for error in self.__errors:
+ if error.fixable:
+ count = count + 1
+ return count
+
+ def apply_fixable_errors(self):
+ for error in self.__errors:
+ if error.fixable:
+ error.apply_fix( self )
+ return True
def get_status(self):
# -1 no ssh connection, 0 not running, 1 service started, 2 can get an http connection
#TODO: ssh
- if not self.is_running():
- return 0
- if not self.is_reachable():
- return 1
- return 2
+ result = self.is_process_running()
+ if result == -1:
+ return -1 # error communicating with apache process
+ if result == 0 :
+ return 0 # apache not running
+ if not self.is_http_reachable():
+ return 1 # cant connect via http
+ return 2 # running
# is service running
- def is_running(self):
+ def is_process_running(self):
# Check if python2 is running
- returncode, output, error = Shell.command.execute(["pidof", "apache2"])
- return len(output.strip()) > 0
+ try:
+ returncode, output, error = self.server.command.execute(["pidof", "apache2"])
+ return len(output.strip())
+ except:
+ return -1
# is http reachable
- def is_reachable(self):
+ def is_http_reachable(self):
try:
- p = urllib2.urlopen( "http://" + self.server )
+ p = urllib2.urlopen( "http://" + self.server.name )
info = p.geturl()
p.close()
return True
@@ -40,26 +234,30 @@
return False
def start(self):
- Shell.command.sudo_execute(["apache2ctl", "start"])
+ self.server.command.sudo_execute(["apache2ctl", "start"])
return
def stop(self):
- #Shell.command.sudo_execute(["apache2ctl", "-k", "graceful"])
- Shell.command.sudo_execute(["apache2ctl", "stop"])
+ #self.server.command.sudo_execute(["apache2ctl", "-k", "graceful"])
+ self.server.command.sudo_execute(["apache2ctl", "stop"])
return
- def restart(self):
- Shell.command.sudo_execute(["apache2ctl", "graceful"])
+ def restart(self, graceful=True):
+ if graceful:
+ self.server.command.sudo_execute(["apache2ctl", "graceful"])
+ else:
+ self.stop()
+ self.start()
return
def test_config(self):
- returncode, output, error = Shell.command.sudo_execute(["apache2ctl", "-S"])
+ returncode, output, error = self.server.command.sudo_execute(["apache2ctl", "-S"])
error = error.strip()
return error.endswith("Syntax OK"), error
def enable_site(self, path):
- Shell.command.execute(["a2ensite", path])
+ self.server.command.execute(["a2ensite", path])
def disable_site(self, path):
- Shell.command.execute(["a2dissite", path])
+ self.server.command.execute(["a2dissite", path])
=== added file 'RapacheCore/ApacheError.py'
--- RapacheCore/ApacheError.py 1970-01-01 00:00:00 +0000
+++ RapacheCore/ApacheError.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,42 @@
+class ApacheError():
+ def __init__(self, title, description, object = None, fixable = False):
+ self.title = title
+ self.description = description
+ self.object = object
+ self.fixable = fixable
+
+ def apply_fix(self, apache):
+ return
+
+class ApacheConfigError(ApacheError):
+ def __init__(self, description):
+ ApacheError.__init__(self, "Apache Config", description)
+
+class ApachePortRequiredVhostError(ApacheError):
+ def __init__(self, vhost):
+ ApacheError.__init__(self, "No port specified : " + vhost.get_server_name(), "When using SSL with apache every virtual host must have a port specified", vhost, True)
+
+ def apply_fix(self, apache):
+ # insure port is set on vhost / object, default to 80 if there is none...
+ default_port = 80
+ vhosts = apache.get_virtual_hosts()
+ if vhosts.has_key('default'):
+ vhost = vhosts['default']
+ if vhost.has_port() and vhost.get_port() != 443:
+ default_port = vhost.get_port()
+
+ vhost = self.object
+ if not vhost.has_port():
+ vhost.set_port(default_port)
+ vhost.save()
+ return
+
+class ApacheDenomalisedVhostError(ApacheError):
+ def __init__(self, vhost):
+ ApacheError.__init__(self, vhost.get_server_name() + " - needs normalising", "why you need to do this", vhost, True)
+
+ def apply_fix(self, apache):
+ # normalise vhost / object
+ self.object.normalize()
+ return
+
=== modified file 'RapacheCore/Configuration.py'
--- RapacheCore/Configuration.py 2008-07-30 21:14:51 +0000
+++ RapacheCore/Configuration.py 2010-05-16 23:57:26 +0000
@@ -21,7 +21,11 @@
SITES_AVAILABLE_DIR = SYSCONFDIR + '/sites-available'
MODS_ENABLED_DIR = SYSCONFDIR + '/mods-enabled'
MODS_AVAILABLE_DIR = SYSCONFDIR + '/mods-available'
+
+NUMBER_OF_BACKUPS = 10
+TEST_CONNECTION_INTERVAL = 3
+LOG_PATH = "/var/log/apache2"
+CONFIG_PATH = "~/.config/rapache"
+
APPPATH = '/usr/bin' #please fill at run-time
GLADEPATH = '/usr/share/rapache/Glade' #please fill at run-time
-NUMBER_OF_BACKUPS = 10
-TEST_CONNECTION_INTERVAL = 30
=== added file 'RapacheCore/Core.py'
--- RapacheCore/Core.py 1970-01-01 00:00:00 +0000
+++ RapacheCore/Core.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,60 @@
+import os
+from RapacheCore.Server import Server
+from RapacheCore.PluginManager import PluginManager
+from RapacheCore import Configuration
+
+class RapacheCore():
+
+ def __init__(self):
+ self.servers = {}
+ self.plugin_manager = PluginManager(self)
+
+ self.current_server = None
+ self.localhost = None
+ self.load_all_servers()
+
+ def set_new_server(self, server, port, username, password):
+ ls = Server(self, server, port, username, password)
+ self.servers[ls.name] = ls
+ self.current_server = ls
+
+ def save(self):
+ content = []
+
+ path = os.path.join(Configuration.CONFIG_PATH, "servers.txt")
+ print "SAVE ", path
+ f = open(path, "w")
+ for key in self.servers:
+ if key != "localhost":
+ s = self.servers[key]
+ if s.creditials_verified or s.saved:
+ f.write(s.name + " " + str(s.ssh_port) + " " + s.username +"\n")
+ f.close()
+
+
+ def load_all_servers(self):
+
+ # TODO: Load saved configs....
+ path = os.path.join(Configuration.CONFIG_PATH, "servers.txt")
+ if os.path.exists(path):
+ f = open(path, "r")
+ for line in f.readlines():
+ parts = line.strip().split(' ')
+ if len(parts) > 0:
+ server = parts[0]
+ port = 22
+ username = None
+ if len(parts) > 1: port = int(parts[1])
+ if len(parts) > 2: username = parts[2]
+ s = Server(self, server, port, username)
+ s.saved = True
+ self.servers[parts[0]] = s
+
+ # local apache
+ if self.servers.has_key("localhost"):
+ del self.servers["localhost"]
+ if( os.path.isdir( Configuration.SITES_AVAILABLE_DIR ) and os.path.isdir( Configuration.SITES_ENABLED_DIR )):
+ self.current_server = Server(self)
+ self.servers["localhost"] = self.current_server
+
+ return
=== modified file 'RapacheCore/Module.py'
--- RapacheCore/Module.py 2008-07-29 10:08:23 +0000
+++ RapacheCore/Module.py 2010-05-16 23:57:26 +0000
@@ -123,7 +123,8 @@
return list
class ModuleModel:
- def __init__(self, name = None):
+ def __init__(self, name = None, apache = None, enabled = False):
+ self.apache = apache
self.defaults = {
'enabled' : False
, 'name' : None
@@ -137,8 +138,9 @@
self.data = self.defaults
if ( name != None ):
+ path = os.path.join(Configuration.MODS_AVAILABLE_DIR, name + ".load" )
self.data[ 'name' ] = name
- self.data[ 'enabled' ] = self.is_enabled()
+ self.data[ 'enabled' ] = enabled
def load (self, name = False):
try:
@@ -154,6 +156,7 @@
content = self.get_source()
self.__get_dependecies(content)
self.parsable = True
+ self.changed = False
except:
#print "Unparsable by me - unsupported"
raise "ModuleUnparsable"
@@ -174,26 +177,9 @@
dependancy = match.groups()[0].strip()
if dependancy != "" : dependancies.append( dependancy )
self.data[ 'dependancies' ] = dependancies
- def is_enabled ( self ):
- orig = self.data[ 'name' ] + ".load"
- dirList = Shell.command.listdir( Configuration.MODS_ENABLED_DIR )
- for fname in dirList:
- try:
- flink = Shell.command.readlink( os.path.join(Configuration.MODS_ENABLED_DIR, fname) )
- flink = os.path.join(os.path.dirname( Configuration.MODS_ENABLED_DIR +"/" ), flink)
- #please note debian brilliantly features a nice set of
- # mixed absolute and relative links. FREAKS !
- # the added "/" is also necessary
- flink = os.path.normpath(flink)
- if ( flink == os.path.join(Configuration.MODS_AVAILABLE_DIR, orig )):
- return True
- except:
- pass
-
- return False
def _write(self, complete_path, content ):
- Shell.command.write_file( complete_path, content )
+ self.apache.server.command.write_file( complete_path, content )
def toggle(self, status ):
"status = True|False"
@@ -206,10 +192,10 @@
#del tokens[ len( tokens ) -1 ]
#name = ".".join(tokens)
name = self.data['name']
- Shell.command.sudo_execute( [command_name, name] )
- self.data['enabled'] = self.is_enabled()
+ self.apache.server.command.sudo_execute( [command_name, name] )
+ self.data['enabled'] = status # assume status worked it will be updated after reload
self.changed = True
-
+ print "TOGGLE"
def get_description(self):
name = self.data['name']
@@ -228,16 +214,17 @@
return os.path.join(Configuration.MODS_AVAILABLE_DIR, self.data['name']+".conf")
def get_backup_files(self):
- return Shell.command.get_backup_files( os.path.join(Configuration.MODS_AVAILABLE_DIR, self.data['name']+".conf"))
+ return self.apache.server.command.get_backup_files( os.path.join(Configuration.MODS_AVAILABLE_DIR, self.data['name']+".conf"))
def get_source ( self ):
- return Shell.command.read_file( os.path.join(Configuration.MODS_AVAILABLE_DIR, self.data['name']+".load"))
+ return self.apache.server.command.read_file( os.path.join(Configuration.MODS_AVAILABLE_DIR, self.data['name']+".load"))
def get_configuration ( self ):
- return Shell.command.read_file( self.get_configuration_file_name() )
+ return self.apache.server.command.read_file( self.get_configuration_file_name() )
def get_configuration_version( self, date_stamp):
- return Shell.command.read_file_version(self.get_configuration_file_name() , date_stamp)
+ return self.apache.server.command.read_file_version(self.get_configuration_file_name() , date_stamp)
def save_configuration (self, content):
self._write(self.get_configuration_file_name(), content)
+ self.changed = True
=== added file 'RapacheCore/Network.py'
--- RapacheCore/Network.py 1970-01-01 00:00:00 +0000
+++ RapacheCore/Network.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+
+from os import popen4
+
+class Networks:
+ def networks_list(self):
+ networks = popen4("""nmap --iflist | grep "[(]" | grep "[(]SHORT[)]" -v | grep "[(]lo[)]" -v | grep "Starting Nmap" -iv | awk '{ print $1 " " $3 }'""")[1].read().split('\n')[:-1]
+ for a in networks:
+ networks[networks.index(a)] = ' '.join(a.split('/')).split()
+ return networks
+
+ def get_computers(self, ip, range = "24"):
+ return popen4('nmap '+ip+'/'+range+" -p22 -v | grep discovered -i | awk '{ print $6 }'")[1].read().split('\n')[:-1]
=== modified file 'RapacheCore/PluginBase.py'
--- RapacheCore/PluginBase.py 2008-09-10 03:25:06 +0000
+++ RapacheCore/PluginBase.py 2010-05-16 23:57:26 +0000
@@ -32,19 +32,18 @@
# Number set when plugin UI is added to notebook
self._tab_number = -1
- def is_module_enabled(self):
+ def is_module_enabled(self, modules):
if self.module:
- module = ModuleModel(self.module)
- module.load()
- #print "STATUS : " + self.module + " - " + str( module.is_enabled())
- return module.is_enabled()
+ if modules.has_key(self.module):
+ module = modules[ self.module ]
+ #print "STATUS : " + self.module + " - " + str( module.is_enabled())
+ return module.data['enabled']
+ return False
return True
- def is_enabled(self):
- enabled = self.is_module_enabled()
-
+ def is_enabled(self, modules):
+ enabled = self.is_module_enabled(modules)
#TODO: Method of activating / deactivating plugins
-
return enabled
# Add item to tools menu
=== modified file 'RapacheCore/PluginManager.py'
--- RapacheCore/PluginManager.py 2008-09-16 13:58:17 +0000
+++ RapacheCore/PluginManager.py 2010-05-16 23:57:26 +0000
@@ -19,8 +19,11 @@
import imp
import sys
import traceback
+import Configuration
+
class PluginManager():
+<<<<<<< TREE
def __init__(self):
print "-- Loading plugins --"
@@ -51,3 +54,83 @@
traceback.print_exc(file=sys.stdout)
+=======
+ def __init__(self, core):
+
+ self.__core = core
+
+ print "-- Loading plugins --"
+ self.plugins = []
+ self.__add(os.path.join(sys.path[0], "plugins"))
+ self.__add(os.path.join(Configuration.CONFIG_PATH, "plugins"))
+ print ""
+
+ def __add(self, pluginpath):
+
+ print "checking plugin folder : " + pluginpath
+
+ if not pluginpath in sys.path:
+ sys.path.insert(0, pluginpath)
+
+ if os.path.exists(pluginpath):
+ for folder in os.listdir(pluginpath):
+ path = os.path.join(pluginpath,folder)
+ if os.path.isdir(path):
+ try:
+ module = __import__(folder + ".plugin")
+ obj = module.plugin.register(self.__core, path)
+ self.plugins.append(obj)
+ print "loaded plugin : " + folder
+ except:
+ print "error loading plugin " + folder
+ traceback.print_exc(file=sys.stdout)
+ print len(self.plugins), " Plugins loaded"
+
+ def init_main_window(self, rapache_window):
+ for plugin in self.__core.plugin_manager.plugins:
+ try:
+ if plugin.is_enabled(self.__core.current_server.apache.get_modules()):
+ menu_item = plugin.init_main_window(rapache_window)
+ if menu_item != None:
+ rapache_window.menu_tools.add(menu_item)
+ menu_item.show()
+ except Exception:
+ traceback.print_exc(file=sys.stdout)
+
+
+ def init_vhost_properties(self, store, label, notebook):
+ for plugin in self.__core.plugin_manager.plugins:
+ try:
+ print plugin
+ if plugin.is_enabled(self.__core.current_server.apache.get_modules()):
+ print "enabled"
+ content, title, pixbuf = plugin.init_vhost_properties()
+ tab_count = notebook.get_n_pages() - 1
+ plugin._tab_number = notebook.insert_page(content, label(title), tab_count)
+ store.append((pixbuf, title, tab_count))
+ content.show()
+ except Exception:
+ traceback.print_exc(file=sys.stdout)
+
+
+ def update_vhost_properties(self, vhost, tab):
+ result = True
+ error = ""
+ for plugin in self.__core.plugin_manager.plugins:
+ try:
+ if plugin.is_enabled(self.__core.current_server.apache.get_modules()) and plugin._tab_number == tab:
+ result, error = plugin.update_vhost_properties(vhost)
+ except Exception:
+ traceback.print_exc(file=sys.stdout)
+ return result, error
+
+
+ def load_vhost_properties(self, vhost, tab):
+ for plugin in self.__core.plugin_manager.plugins:
+ try:
+ if plugin.is_enabled(self.__core.current_server.apache.get_modules()) and plugin._tab_number == tab:
+ plugin.load_vhost_properties(vhost)
+ except Exception:
+ traceback.print_exc(file=sys.stdout)
+
+>>>>>>> MERGE-SOURCE
=== added file 'RapacheCore/Server.py'
--- RapacheCore/Server.py 1970-01-01 00:00:00 +0000
+++ RapacheCore/Server.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,42 @@
+from RapacheCore import Apache
+from RapacheCore import Shell
+from RapacheCore import ShellSSH
+import Configuration
+
+class Server():
+ def __init__(self, core, server_name="", ssh_port="", username="", password=""):
+
+ self.__core = core
+ self.__localhost = False
+
+ # SSH connection details
+ self.name = server_name
+ self.ssh_port = ssh_port
+ self.username = username
+ self.password = password
+
+ self.creditials_verified = False
+ self.saved = False
+
+ if self.name:
+ self.creditials_verified = False
+ self.command = ShellSSH.CommandHandler(self, server_name, ssh_port, username, password)
+ else:
+ self.__localhost = True
+ self.creditials_verified = True
+ self.name = "localhost"
+ self.command = Shell.CommandHandler(self)
+
+ self.apache = Apache.Apache2(self)
+
+ def get_display_name(self):
+ if not self.__localhost:
+ return self.name #self.username +"@" + self.name + ":" + str(self.ssh_port)
+ else:
+ return "< Local Machine >"
+
+ def get_nautilus_browse_string(self, path):
+ if self.__localhost:
+ return path
+ else:
+ return "ssh://%s@%s:%s%s" % (self.username, self.name, self.ssh_port, path)
=== modified file 'RapacheCore/Shell.py'
--- RapacheCore/Shell.py 2008-09-08 00:18:34 +0000
+++ RapacheCore/Shell.py 2010-05-16 23:57:26 +0000
@@ -43,40 +43,32 @@
import glob
import operator
import Configuration
-
-class CommandLogEntry:
-
- def __init__(self, command):
- self.command = subprocess.list2cmdline(command)
- self.returncode = None
- self.output = None
- self.error = None
-
+import paramiko
class CommandHandler:
- def __init__(self, ssh_server="localhost", ssh_port=None, ssh_username=None, ssh_password=None):
+ def __init__(self, server):
+ self.__server = server
# Verboseness
# 0 = No output
# 1 = prints the command and its return code
# 2 = Command output
self.auto_backup = False
- self.verbose = 0
+ self.verbose = 2
self.command_log = []
# let's make the object stateful, no duplicate password
# typing needed for our users
self.__password = None
+
+ def test(self):
+ return True
+ def close(self):
+ return True
- # SSH connection details
- self.ssh_server = ssh_server
- self.ssh_port = ssh_port
- self.ssh_username = ssh_username
- self.ssh_password = ssh_password
-
def __get_backup_path(self, path):
# ~/.rapache/backup/server/file_path/datestamp.bak
- backup_path = os.path.expanduser(os.path.join("~/.rapache/backup", self.ssh_server, path[1:]))
+ backup_path = os.path.expanduser(os.path.join(Configuration.CONFIG_PATH, "backup", self.__server.get_display_name(), path[1:]))
if not os.path.exists( os.path.dirname(backup_path) ):
os.makedirs(os.path.dirname(backup_path))
return backup_path
@@ -175,7 +167,11 @@
os.remove(local_path)
def listdir(self, path):
- return os.listdir(path)
+ try:
+ return os.listdir(path)
+ except OSError:
+ dir_list = os.popen4('gksu ls '+path)[1].read().split('\n')[:-1]
+ return dir_list
def create_complete_path ( self, complete_path ):
if not self.exists( complete_path ):
@@ -203,7 +199,7 @@
def move(self, source, destination):
self.sudo_execute( ["mv", source, destination] )
-
+
def __get_password(self, description, prompt="Password: "):
ctx = gksu2.Context()
@@ -256,7 +252,10 @@
else:
self.__password = None
return True
-
+
+
+
+
# Description will be discarded
def execute(self, command, description = None ):
returncode = 0
@@ -352,10 +351,6 @@
return output.split("\n")
return []
-# Look ma'! A singleton !
-command = CommandHandler()
-#command.verbose = 1
-
if __name__ == "__main__":
c = CommandHandler()
c.verbose = 2
@@ -364,4 +359,4 @@
print c.sudo_reset()
code, out, err = c.sudo_execute(["head", "/var/log/syslog"], "Pwd FTW !")
code, out, err = c.sudo_execute(["head", "/var/log/syslog"], "Pwd FTW !")
-
+
=== added file 'RapacheCore/ShellSSH.py'
--- RapacheCore/ShellSSH.py 1970-01-01 00:00:00 +0000
+++ RapacheCore/ShellSSH.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,257 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza, Jason Taylor, Emanuele Gentili
+#
+# This program 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.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+
+import sys
+import gksu2
+import tempfile
+import getpass
+import subprocess
+import sys
+from subprocess import *
+import traceback
+import time
+import glob
+import operator
+import Configuration
+import paramiko
+import Shell
+
+# http://www.lag.net/paramiko/docs/
+
+class CommandHandler(Shell.CommandHandler):
+
+ def __init__(self, server, ssh_server, ssh_port, ssh_username, ssh_password):
+ Shell.CommandHandler.__init__ (self, server)
+
+ self.server = server
+ self.__sftp = None
+ self.__transport = None
+
+
+ def __open(self):
+ paramiko.util.log_to_file(os.path.join(Configuration.CONFIG_PATH,'paramiko.log'))
+
+ if not self.__transport or not self.__transport.is_active():
+ self.__server.creditials_verified = False
+ self.__sftp = None
+ print "SSH Opening connection to ", self.server.name, self.server.ssh_port
+ self.__transport = paramiko.Transport((self.server.name, self.server.ssh_port))
+ if self.__transport:
+ try:
+ self.__transport.connect(username=self.server.username, password=self.server.password)
+ except:
+ self.close()
+ return
+ try:
+ self.__sftp = paramiko.SFTPClient.from_transport(self.__transport)
+ except:
+ self.close()
+ return
+ self.__server.creditials_verified = True
+
+ def close(self):
+ if self.__transport.is_active():
+ print "SSH close connection"
+ self.__transport.close()
+
+ def test(self):
+ try:
+ self.__open()
+ return self.__server.creditials_verified
+ except Exception, Text:
+ print Text
+ return False
+
+ def exists(self, path):
+ print "SSH file exists ", path
+ self.__open()
+ try:
+ r = self.__sftp.stat( path )
+ except IOError:
+ return False
+ return True
+
+ def move(self, source, destination):
+ print "SSH move ", path
+ self.__open()
+ self.sudo_execute( ["mv", source, destination] )
+
+ def readlink(self, path):
+ print "SSH read link ", path
+ self.__open()
+ try:
+ return self.__sftp.readlink(path)
+ except:
+ return None
+
+ def listdir(self, path):
+ print "SSH listdir ", path
+ self.__open()
+ return self.__sftp.listdir(path)
+
+ def write_file(self, path, content, backup=True):
+
+ if not backup or self.create_backup(path, content):
+
+ if self.verbose >= 1:
+ print "WRITING : " + path
+
+ # Update local backup copy
+ if backup:
+ local_path = self.__get_backup_path(path)
+ else:
+ f, local_path = tempfile.mkstemp()
+
+ f = open(local_path, "w")
+ f.write(content)
+ f.close()
+
+ temppath = os.path.join("/tmp/rapache_upload_" + os.path.basename(path))
+
+ print "SSH write file ", path
+ print local_path
+ print temppath
+ self.__open()
+ self.__sftp.put(local_path, temppath)
+ self.sudo_execute(["mv", temppath, path])
+
+ # remove the local copy if no backups
+ if not backup:
+ os.remove(local_path)
+
+
+ def read_file(self, path):
+ print "SSH read file " , path
+ try:
+ self.__open()
+ f = self.__sftp.open(path, 'r')
+ data = f.read()
+ f.close()
+ return data
+ except:
+ return None
+
+
+ def sudo_execute(self, command):
+ return self.execute(["sudo", "-S"] + command, subprocess.list2cmdline(["echo", self.server.password]) + " | ")
+
+ def execute(self, command, precommand=""):
+ print "SSH execute ", command
+ self.__open()
+ chan = self.__transport.open_session()
+ chan.exec_command(precommand + subprocess.list2cmdline(command))
+ return_code = chan.recv_exit_status()
+
+ read_size = 100
+
+ stdout = ""
+ chunk = chan.recv(read_size)
+ while len(chunk) > 0:
+ stdout = stdout + chunk
+ chunk = chan.recv(read_size)
+
+ stderr = ""
+ chunk = chan.recv_stderr(read_size)
+ while len(chunk) > 0:
+ stderr = stderr + chunk
+ chunk = chan.recv_stderr(read_size)
+
+ chan.close()
+
+ return (return_code, stdout, stderr)
+
+ def __get_password(self, description, prompt="Password: "):
+
+ ctx = gksu2.Context()
+ ctx.set_message(description)
+ ctx.set_command(subprocess.list2cmdline(["ls","/root"]))
+ ctx.set_grab(True)
+
+ return gksu2.ask_password_full(ctx, prompt) # how does su_full invoke keychain options?
+
+ def __sudo_popen (self, command, password ):
+ #don't enable the following line
+ #print "using password:", password
+
+ # prepend sudo to command and allow piping in
+ command.insert(0, "sudo")
+ command.insert(1, "-S")
+ p = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+ #we need a try catch to avoid tracebacks to be printed
+ #as they would show the password
+ try:
+ if p.stdin and not p.stdin.closed:
+ p.stdin.write( password )
+ except IOError:
+ pass # catch the IOError as its meaningless
+ except:
+ #don't enable the following line as you password
+ #will be printed out
+ #traceback.print_exc() #<-- CAUTION !
+
+ print "ERROR: in __sudo_popen()"
+ pass
+ return p
+
+ def is_auth_needed (self):
+ return False
+
+ def sudo_reset (self):
+ self.__password = None
+ command = ['sudo', '-K' ]
+ p = Popen( command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+ output, error = p.communicate()
+ returncode = p.returncode
+ self.__output(command, returncode, output, error)
+
+ def ask_password(self, description='' ):
+ return True
+
+ def sudo_read_file(self, path):
+ returncode, output, error = self.sudo_execute( ["cat", path] )
+ if returncode == 0:
+ return output
+ return ""
+
+ def sudo_exists(self, path):
+ returncode, output, error = self.sudo_execute( ["ls", path] )
+ return returncode == 0
+
+ def sudo_listdir(self, path):
+ returncode, output, error = self.sudo_execute( ["ls", "-1", path] )
+ if returncode == 0:
+ return output.split("\n")
+ return []
+
+if __name__ == "__main__":
+ c = CommandHandler()
+ c.verbose = 2
+ #print c.is_auth_needed()
+
+ print c.sudo_reset()
+ code, out, err = c.sudo_execute(["head", "/var/log/syslog"], "Pwd FTW !")
+ code, out, err = c.sudo_execute(["head", "/var/log/syslog"], "Pwd FTW !")
+
+
+
+
+
+
+
+
=== added file 'RapacheCore/Threads.py'
--- RapacheCore/Threads.py 1970-01-01 00:00:00 +0000
+++ RapacheCore/Threads.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,10 @@
+import threading
+import time
+
+# Define threaded attribute
+def threaded(f):
+ def wrapper(*args):
+ t = threading.Thread(target=f, args=args)
+ t.setDaemon(True) # wont keep app alive
+ t.start()
+ return wrapper
=== added file 'RapacheCore/Utils.py'
--- RapacheCore/Utils.py 1970-01-01 00:00:00 +0000
+++ RapacheCore/Utils.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,6 @@
+
+
+def match_backup_files ( fname ):
+ if re.match( '.*[~]\s*$', fname ) != None : return True
+ if re.match( '.*.swp$', fname ) != None : return True
+ return False
=== modified file 'RapacheCore/VirtualHost.py'
--- RapacheCore/VirtualHost.py 2008-09-15 11:25:35 +0000
+++ RapacheCore/VirtualHost.py 2010-05-16 23:57:26 +0000
@@ -32,8 +32,10 @@
from RapacheCore import Shell
VHOST_TEMPLATE = """#created for you by Rapache
-<VirtualHost *:80>
-
+<VirtualHost *>
+ #ServerAdmin webmaster@xxxxxxxxxxx
+ ServerName example
+ DocumentRoot /var/www/examplepath
</VirtualHost>"""
@@ -44,6 +46,7 @@
def is_denormalized_vhost ( fname ):
try:
+ print "is_denormalized_vhost"
flink = Shell.command.readlink( os.path.join(Configuration.SITES_ENABLED_DIR, fname))
flink = os.path.join(os.path.dirname( Configuration.SITES_AVAILABLE_DIR ), flink)
#no exceptions ? Means it's a link
@@ -55,33 +58,25 @@
dest = os.path.join(Configuration.SITES_AVAILABLE_DIR, fname)
return Shell.command.exists( dest )
-def normalize_vhost( fname ):
- print "Normalizing:", fname
- orig = os.path.join(Configuration.SITES_ENABLED_DIR, fname)
- dest = os.path.join(Configuration.SITES_AVAILABLE_DIR, fname)
- if ( Shell.command.exists( dest ) == True ):
- print fname, "already exists in available dir. not even trying"
- return False
- command = ['mv',orig,dest]
- code, output, error = Shell.command.sudo_execute( command )
- return ( code == 0 )
- return Shell.command.exists( dest )
# Replacment that uses new parser.....
class VirtualHostModel():
- def __init__(self, name = None, plugin_manager = None):
+ def __init__(self, name = None, apache = None, enabled = False):
self.__name = name
self.__parser = Parser()
+ self.apache = apache
+ self.__is_default = name == "default"
self.__server_alias = []
- self.__is_default = name == "default"
- self.is_new = name == "" or not Shell.command.exists( self.get_source_filename() )
+ self.is_new = name == "" or not self.apache.server.command.exists( self.get_source_filename() )
self.data = None
self.parsable = True
- self.enabled = self.is_enabled()
+ self.enabled = enabled
self.hack_hosts = False
self.config = None
+ self.changed = False
+
if self.is_new:
self.__parser = Parser()
self.__parser.set_from_str( VHOST_TEMPLATE )
@@ -89,8 +84,8 @@
else:
try:
self.load(None)
+ self.__server_alias = self.get_text-server_alias()
self.parsable = True
- self.__server_alias = self.get_server_alias()
if self.__name != self.get_server_name():
print "FILE NAME MISMATCH"
@@ -102,8 +97,10 @@
def load(self, name = False):
try:
self.__parser = Parser()
- self.__parser.load( self.get_source_filename() )
+ content = self.apache.server.command.read_file(self.get_source_filename())
+ self.__parser.set_from_str( content )
self.config = self.__parser.rsearch("VirtualHost")[0]
+ self.changed = False
return True
except:
self.parsable = False
@@ -113,6 +110,7 @@
current_parser = self.__parser
try:
self.__parser = Parser()
+
self.__parser.set_from_str( content )
self.config = self.__parser.rsearch("VirtualHost")[0]
return True
@@ -121,7 +119,7 @@
return False
def save(self, content=None):
- if not Shell.command.ask_password(): return
+ if not self.apache.server.command.ask_password(): return
# Get parser content
if not content: content = self.__parser.get_as_str()
@@ -132,11 +130,11 @@
print "Creating virtualhost: " + ServerName
print "Folder: " + DocumentRoot
- if ( Shell.command.exists( DocumentRoot ) == False ):
+ if ( self.apache.server.command.exists( DocumentRoot ) == False ):
print "Folder " + DocumentRoot + " does not exist"
- Shell.command.create_complete_path( DocumentRoot )
+ self.apache.server.command.create_complete_path( DocumentRoot )
- if ( Shell.command.exists( DocumentRoot ) == False ):
+ if ( self.apache.server.command.exists( DocumentRoot ) == False ):
self.error( "Could not create target folder" ) #TODO fix this
return False
@@ -147,22 +145,19 @@
# if new then make sure to update name before saving
if self.is_new: self.__name = ServerName
- Shell.command.write_file(self.get_source_filename(), content)
-
- #not needed anymore (nor invoked)
+ self.apache.server.command.write_file(self.get_source_filename(), content)
+
+ self.changed = True
+
if self.hack_hosts:
- # remove old one
- Shell.command.sudo_execute ( [os.path.join(Configuration.APPPATH, "hosts-manager"), '-r', self.__name ] )
-
- Shell.command.sudo_execute ( [os.path.join(Configuration.APPPATH, "hosts-manager"), '-a', ServerName ] )
+ self.apache.server.command.sudo_execute ( [os.path.join(Configuration.APPPATH, "hosts-manager"), '-r', self.__name ] )
+ self.apache.server.command.sudo_execute ( [os.path.join(Configuration.APPPATH, "hosts-manager"), '-a', ServerName ] )
for alias in self.__server_alias:
- Shell.command.sudo_execute ( [os.path.join(Configuration.APPPATH, 'hosts-manager'), '-r', alias ])
+ self.apache.server.command.sudo_execute ( [os.path.join(Configuration.APPPATH, 'hosts-manager'), '-r', alias ])
- for alias in self.get_server_alias():
- Shell.command.sudo_execute ( [os.path.join(Configuration.APPPATH, 'hosts-manager'), '-a', alias ])
-
- self.__server_alias = self.get_server_alias()
+ for alias in self.config.ServerAlias:
+ self.apache.server.command.sudo_execute ( [os.path.join(Configuration.APPPATH, 'hosts-manager'), '-a', alias ])
if self.is_new:
self.toggle( True ) #activate by default
@@ -170,7 +165,7 @@
else:
# If already existed may need to rename the file
- old_enabled = self.is_enabled()
+ old_enabled = self.enabled
new_name = os.path.join(Configuration.SITES_AVAILABLE_DIR, ServerName)
old_name = os.path.join(Configuration.SITES_AVAILABLE_DIR, self.__name)
@@ -178,11 +173,11 @@
print "old name", old_name
print "new name", new_name
- if old_name != new_name and Shell.command.exists( new_name ) == False:
+ if old_name != new_name and self.apache.server.command.exists( new_name ) == False:
print "Server name changed, updating conf filename"
self.toggle( False )
- Shell.command.move( old_name, new_name )
- if Shell.command.exists( new_name ) == True:
+ self.apache.server.command.move( old_name, new_name )
+ if self.apache.server.command.exists( new_name ) == True:
# success ! we need to reload vhost with the new name
self.__name = ServerName
self.load()
@@ -198,7 +193,7 @@
return True
def get_source ( self ):
- return Shell.command.read_file(self.get_source_filename())
+ return self.apache.server.command.read_file(self.get_source_filename())
def get_source_generated( self ):
return self.__parser.get_as_str()
@@ -209,40 +204,21 @@
return os.path.join(Configuration.SITES_AVAILABLE_DIR, self.__name)
def get_backup_files(self):
- return Shell.command.get_backup_files( os.path.join(Configuration.SITES_AVAILABLE_DIR, self.__name))
+ return self.apache.server.command.get_backup_files( os.path.join(Configuration.SITES_AVAILABLE_DIR, self.__name))
def get_source_version ( self, timestamp ):
- return Shell.command.read_file_version(self.get_source_filename(), timestamp)
+ return self.apache.server.command.read_file_version(self.get_source_filename(), timestamp)
def delete( self ):
"Deletes a VirtualHost configuration file"
if not self.is_new:
- if ( self.is_enabled() ):
- self.toggle( False )
- Shell.command.sudo_execute( [ 'rm', self.get_source_filename() ])
+ self.toggle( False )
+ self.apache.server.command.sudo_execute( [ 'rm', self.get_source_filename() ])
def is_default( self ):
return self.__is_default
def is_editable( self ):
return (self.parsable and not self.config == None)
-
- def is_enabled ( self ):
- orig = self.get_source_filename()
- dirList = Shell.command.listdir( Configuration.SITES_ENABLED_DIR )
- for fname in dirList:
- try:
- flink = Shell.command.readlink( os.path.join(Configuration.SITES_ENABLED_DIR, fname) )
- flink = os.path.join(os.path.dirname( Configuration.SITES_ENABLED_DIR +"/" ), flink)
- # please note debian features a nice set of
- # mixed absolute and relative links. FREAKS !
- # the added "/" is also necessary
- flink = os.path.normpath(flink)
- if ( flink == orig ):
- return True
- except:
- pass
-
- return False
def toggle( self, status ):
"status = True|False"
@@ -252,8 +228,8 @@
command = "a2dissite"
# set new value
- Shell.command.sudo_execute( [ command, self.__name ] )
- self.enabled = self.is_enabled()
+ self.apache.server.command.sudo_execute( [ command, self.__name ] )
+ self.enabled = status
self.changed = True
@@ -265,7 +241,7 @@
except:
pass
return self.__name
-
+
def get_document_root(self):
try:
if self.config.DocumentRoot:
@@ -285,14 +261,16 @@
def get_icon(self):
# TODO: This MUST return a local path...
# TODO: Try url for a favicon as well
- DocumentRoot = self.get_document_root()
- if DocumentRoot != None:
- favicon = os.path.join(DocumentRoot, "favicon.ico")
- if ( os.path.exists( favicon ) ):
- return favicon
- return os.path.join( Configuration.GLADEPATH, 'browser.png' )
-
-
+ if self.parsable:
+ DocumentRoot = self.get_document_root()
+ if DocumentRoot != None:
+ favicon = os.path.join(DocumentRoot, "favicon.ico")
+ if ( os.path.exists( favicon ) ):
+ return favicon
+ return os.path.join( Configuration.GLADEPATH, 'browser.png' )
+ return None
+
+
def has_port(self):
if self.parsable and self.config:
value = self.config.value
@@ -309,6 +287,7 @@
if len(tokens) < 2: return None
if tokens[-1] =="*": return None
return int(tokens[-1])
+
def set_port(self, portnumber):
value = self.config.value
@@ -330,3 +309,34 @@
tokens[-1] = str( portnumber )
value = ":".join( tokens[:-1] )
self.config.value = value
+
+ def clone(self):
+ return VirtualHostModel(self.__name, self.apache, self.enabled)
+
+
+ def is_denormalized_vhost ( self ):
+ if self.is_new: return False
+ try:
+ flink = self.apache.server.command.readlink( os.path.join(Configuration.SITES_ENABLED_DIR, self.__name))
+ return True
+ except:
+ return False
+ return False
+
+ def normalize():
+ print "Normalizing:", self.__name
+ orig = os.path.join(Configuration.SITES_ENABLED_DIR, self.__name)
+ dest = os.path.join(Configuration.SITES_AVAILABLE_DIR, self.__name)
+ if ( self.apache.server.command.exists( dest ) == True ):
+ print fname, "already exists in available dir. not even trying"
+ return False
+ command = ['mv', orig, dest]
+ code, output, error = self.apache.server.command.sudo_execute( command )
+ return ( code == 0 )
+
+ #if fixed:
+ # Shell.command.sudo_execute ( [Configuration.APPPATH+'/hosts-manager', '-a',name])
+ #else :
+ # Shell.command.sudo_execute ( [Configuration.APPPATH+'/hosts-manager', '-r',name])
+ # set new value
+
=== modified file 'RapacheGtk/CheckListView.py'
--- RapacheGtk/CheckListView.py 2008-08-07 22:16:32 +0000
+++ RapacheGtk/CheckListView.py 2010-05-16 23:57:26 +0000
@@ -21,8 +21,9 @@
COLUMN_FIXED,
COLUMN_ICON,
COLUMN_SEVERITY,
- COLUMN_MARKUP
-) = range(4)
+ COLUMN_MARKUP,
+ COLUMN_OBJECT
+) = range(5)
from RapacheCore import Configuration
import RapacheCore.Observer
@@ -59,6 +60,9 @@
def load (self):
raise "AbstractMethod", "Please override this"
+ def clear(self):
+ self._reset_model()
+
def _reset_model (self):
lstore = self.get_model()
if ( lstore == None ):
@@ -72,7 +76,8 @@
gobject.TYPE_BOOLEAN,
gtk.gdk.Pixbuf,
gobject.TYPE_STRING,
- gobject.TYPE_STRING)
+ gobject.TYPE_STRING,
+ object)
return lstore
def __toggled(self, *args, **kwargs):
@@ -123,7 +128,9 @@
rows = selection.get_selected_rows()[1][0]
num_row = rows[0]
model = self.get_model()
- name = model[ num_row ][COLUMN_SEVERITY]
+ #if model[ num_row ][COLUMN_OBJECT]:
+ return model[ num_row ][COLUMN_OBJECT]
+ #name = model[ num_row ][COLUMN_SEVERITY]
except IndexError:
return None
return name
=== added file 'RapacheGtk/Connect.py'
--- RapacheGtk/Connect.py 1970-01-01 00:00:00 +0000
+++ RapacheGtk/Connect.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza, Jason Taylor, Emanuele Gentili
+#
+# This program 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.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+try:
+ import pygtk
+ pygtk.require("2.0")
+except:
+ pass
+try:
+ import gtk
+ import gtk.glade
+except:
+ sys.exit(1)
+
+import os
+from RapacheCore import Configuration
+
+class ConnectionDetails:
+
+ def __init__(self):
+
+
+ gladefile = os.path.join(Configuration.GLADEPATH, "connect.glade")
+ wtree = gtk.glade.XML(gladefile)
+
+ self.window = wtree.get_widget("dialog_connect")
+
+ self.entry_server = wtree.get_widget("entry_server")
+ self.entry_username = wtree.get_widget("entry_username")
+ self.entry_password = wtree.get_widget("entry_password")
+ self.spinbutton_port = wtree.get_widget("spinbutton_port")
+
+ signals = {
+ "on_button_connect_clicked" : self.on_button_connect_clicked,
+ "on_button_cancel_clicked" : self.on_button_cancel_clicked
+ }
+ wtree.signal_autoconnect(signals)
+ # add on destroy to quit loop
+ self.window.connect("destroy", self.on_destroy)
+
+ self.return_value = None
+
+ def on_button_connect_clicked(self, widget):
+
+ self.return_value = self.entry_server.get_text(), self.spinbutton_port.get_value_as_int(), self.entry_username.get_text(), self.entry_password.get_text()
+ self.window.destroy()
+ return
+
+ def on_button_cancel_clicked(self, widget):
+ self.window.destroy()
+ return
+
+ def run(self):
+ self.window.show()
+ gtk.main()
+ return self.return_value
+
+ def load (self, server, port, username):
+ self.entry_server.set_text(server)
+ self.entry_username.set_text(username)
+ self.spinbutton_port.set_value( port )
+
+ return
+
+ def on_destroy(self, widget, data=None):
+ gtk.main_quit()
+
=== modified file 'RapacheGtk/DesktopEnvironment.py'
--- RapacheGtk/DesktopEnvironment.py 2008-09-10 02:24:24 +0000
+++ RapacheGtk/DesktopEnvironment.py 2010-05-16 23:57:26 +0000
@@ -43,8 +43,8 @@
def open_dir( path ):
# just call this locally as it wont apply over ssh
command = ['nautilus', path, '--no-desktop']
-
- if os.access(path, os.W_OK):
+ print path
+ if path.startswith("ssh://") or os.access(path, os.W_OK):
subprocess.Popen( command )
else:
subprocess.Popen( ['gksu', subprocess.list2cmdline(command)] )
=== modified file 'RapacheGtk/EditGeneric.py'
--- RapacheGtk/EditGeneric.py 2008-09-08 03:31:45 +0000
+++ RapacheGtk/EditGeneric.py 2010-05-16 23:57:26 +0000
@@ -32,12 +32,12 @@
import RapacheGtk.GuiUtils
from RapacheCore.Module import *
from RapacheGtk import GuiUtils
-import RapacheCore.Shell
class EditGenericWindow:
- def __init__(self):
-
+ def __init__(self, core):
+ self.core = core
+
gladefile = os.path.join(Configuration.GLADEPATH, "edit_generic.glade")
wtree = gtk.glade.XML(gladefile)
@@ -64,7 +64,7 @@
def on_button_restore_version_clicked(self, widget):
buf = self.text_view_source.get_buffer()
- buf.set_text( Shell.command.read_file( self.file_path ) )
+ buf.set_text( self.core.current_server.command.read_file( self.file_path ) )
if self.text_view_source.get_buffer().get_modified():
md = gtk.MessageDialog(self.window, flags=0, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_OK_CANCEL, message_format="Are you sure, you will lose all your current changes")
@@ -76,10 +76,10 @@
selected = self.combobox_backups.get_active()
if selected == 0:
- buf.set_text( Shell.command.read_file( self.file_path ) )
+ buf.set_text( self.core.current_server.command.read_file( self.file_path ) )
else:
value = self.combobox_backups.get_active_text()[7:]
- buf.set_text( Shell.command.read_file_version( self.file_path, value ) )
+ buf.set_text( self.core.current_server.command.read_file_version( self.file_path, value ) )
buf.set_modified(False)
@@ -92,8 +92,8 @@
buff = self.text_view_source.get_buffer()
text = buff.get_text(buff.get_start_iter(), buff.get_end_iter())
- Shell.command.write_file(self.file_path, text)
-
+ self.core.current_server.command.write_file(self.file_path, text)
+ self.return_value = True
self.window.destroy()
return
@@ -108,13 +108,13 @@
self.window.set_title("Edit " + path)
self.label_path.set_text( path )
- for file in Shell.command.get_backup_files( path ):
+ for file in self.core.current_server.command.get_backup_files( path ):
self.combobox_backups.append_text("Backup " + file[0][-21:-4])
self.combobox_backups.set_active(0)
buf = self.text_view_source.get_buffer()
- buf.set_text( Shell.command.read_file( path ) )
+ buf.set_text( self.core.current_server.command.read_file( path ) )
buf.set_modified(False)
return
=== modified file 'RapacheGtk/ModuleGui.py'
--- RapacheGtk/ModuleGui.py 2008-09-05 02:43:18 +0000
+++ RapacheGtk/ModuleGui.py 2010-05-16 23:57:26 +0000
@@ -50,7 +50,6 @@
from RapacheCore.Module import *
from RapacheGtk import GuiUtils
import RapacheGtk.DesktopEnvironment as Desktop
-import RapacheCore.Shell
def open_module_doc( name ):
if ( name == None ): return False
@@ -128,23 +127,23 @@
buf.set_modified(False)
- def load (self, name ):
+ def load (self, module ):
# self.window.set_title(name)
- self.module = ModuleModel ( name )
+ self.module = module
#self.module.load()
self.__set_module_conf( self.module.get_configuration() )
- self.label_module.set_markup("<b><big>Apache2 Module : " + name + "</big></b>")
+ self.label_module.set_markup("<b><big>Apache2 Module : " + module.data['name'] + "</big></b>")
self.label_module_description.set_markup("<i>" + self.module.get_description() + "</i>")
self.label_path.set_text( "File : " + self.module.get_configuration_file_name() )
for file in self.module.get_backup_files():
self.combobox_module_backups.append_text("Backup " + file[0][-21:-4])
# Load UI Plugins
- for plugin in self.parent.plugin_manager.plugins:
- if plugin.module == name:
+ for plugin in self.parent.core.plugin_manager.plugins:
+ if plugin.module == module.data['name']:
try:
- print "Loading plugin " + name
+ print "Loading plugin " + module.data['name']
plugin.load_module_properties(self.notebook, self.module)
except Exception:
traceback.print_exc(file=sys.stdout)
@@ -159,7 +158,7 @@
buff = self.text_view_module_conf.get_buffer()
text = buff.get_text(buff.get_start_iter(), buff.get_end_iter())
- mod = ModuleModel( name )
+ mod = self.module
mod.save_configuration( text )
#self.parent.refresh_vhosts()
=== added file 'RapacheGtk/Progress.py'
--- RapacheGtk/Progress.py 1970-01-01 00:00:00 +0000
+++ RapacheGtk/Progress.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza, Jason Taylor, Emanuele Gentili
+#
+# This program 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.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+try:
+ import pygtk
+ pygtk.require("2.0")
+except:
+ pass
+try:
+ import gtk
+ import gtk.glade
+except:
+ sys.exit(1)
+
+import os
+
+class Progress:
+
+ def __init__(self, path):
+
+ # The path to the plugin
+ self.glade_path = path
+
+ gladefile = os.path.join(path, "progress.glade")
+ wtree = gtk.glade.XML(gladefile)
+
+ self.window = wtree.get_widget("dialog_progress")
+
+ self.entry_username = wtree.get_widget("entry_username")
+ self.entry_password = wtree.get_widget("entry_password")
+ self.entry_password2 = wtree.get_widget("entry_password2")
+
+ signals = {
+ "on_button_apply_clicked" : self.on_button_apply_clicked,
+ "on_button_close_clicked" : self.on_button_close_clicked
+ }
+ wtree.signal_autoconnect(signals)
+ # add on destroy to quit loop
+ self.window.connect("destroy", self.on_destroy)
+
+ self.return_value = None
+
+ def on_button_close_clicked(self, widget):
+ self.window.destroy()
+ return
+
+ def run(self):
+ self.window.show()
+
+ gtk.main()
+ return self.return_value
+
+ def load (self):
+ return
+
+ def on_destroy(self, widget, data=None):
+ gtk.main_quit()
+
=== modified file 'RapacheGtk/RapacheGui.py'
--- RapacheGtk/RapacheGui.py 2008-09-15 06:53:55 +0000
+++ RapacheGtk/RapacheGui.py 2010-05-16 23:57:26 +0000
@@ -32,11 +32,11 @@
import gtk
import os
import re
+import time
import threading
-import time
import copy
-
+from RapacheGtk.Threads import threaded
from RapacheGtk.VirtualHostGui import VirtualHostWindow
from RapacheGtk.ModuleGui import ModuleWindow
from RapacheCore.PluginManager import PluginManager
@@ -52,36 +52,30 @@
from RapacheGtk.EventDispatcher import Master
import subprocess
import RapacheGtk.DesktopEnvironment as Desktop
+from RapacheGtk.Connect import ConnectionDetails
import traceback
+from TrayIcon import *
data = \
[(False, "Loading", "please wait" )]
APPNAME="Rapache"
-APPVERSION="0.7"
+APPVERSION="0.6"
# Turn on gtk threading
gtk.gdk.threads_init()
-# Define threaded attribute
-def threaded(f):
- def wrapper(*args):
- t = threading.Thread(target=f, args=args)
- t.setDaemon(True) # wont keep app alive
- t.start()
- return wrapper
-
class MainWindow( RapacheCore.Observer.Observable ) :
"""This is an Hello World Rapacheefication application"""
- def __init__(self, *args, **kwargs):
- super (MainWindow, self).__init__ (*args, **kwargs)
+ def __init__(self, core):
+ super (MainWindow, self).__init__ ()
Master.register(self)
- self.denormalized_virtual_hosts = {}
- self.plugin_manager = PluginManager()
- self.apache = Apache2()
+ self.core = core
+ self.status = 0 #0 - connected, 1 attempting
+ self.__pulse_text = " "
+ self.__pulse_flag = False
- #gnome.init(APPNAME, APPVERSION)
self.gladefile = Configuration.GLADEPATH + "/" + "main.glade"
self.xml = gtk.glade.XML(self.gladefile)
#Create our dictionary and connect it
@@ -100,89 +94,244 @@
"on_button_hide_warning_clicked" : self.on_button_hide_warning_clicked,
"quit" : self.quit,
"on_menuitem_stop_apache_activate" : self.on_menuitem_stop_apache_activate,
- "on_button_open_log_clicked" : self.on_button_open_log_clicked
+ "on_button_open_log_clicked" : self.on_button_open_log_clicked,
+ "on_button_connection_clicked" : self.on_button_connection_clicked
}
gtk.window_set_default_icon_from_file(os.path.join( Configuration.GLADEPATH, 'icon_cadsoft_eagle_golden.svg'))
self.xml.signal_autoconnect(dic)
GuiUtils.change_button_label ( self.xml.get_widget( 'restart_apache' ), "Restart Apache" )
- #GuiUtils.change_button_label ( self.xml.get_widget( 'fix_vhosts' ), "Fix Virtual Hosts" )
- self.statusbar_server_status = self.xml.get_widget( 'statusbar_server_status' )
+
+ self.label_server_status = self.xml.get_widget( 'label_server_status' )
self.image_apache_status = self.xml.get_widget( 'image_apache_status' )
self.main_window = self.xml.get_widget("MainWindow")
self.menuitem_stop_apache = self.xml.get_widget("menuitem_stop_apache")
self.menuitem_start_apache = self.xml.get_widget("menuitem_start_apache")
self.menuitem_restart_apache = self.xml.get_widget("menuitem_restart_apache")
- #hereby we create lists
- self.create_vhost_list()
- self.create_modules_list()
- self.create_errors_list()
- #hereby we fill them
- self.refresh_lists(False)
-
+ self.menu_tools = self.xml.get_widget( 'menu_tools' )
+ self.treeview_bookmarks = self.xml.get_widget( 'treeview_bookmarks' )
+ self.combobox_log = self.xml.get_widget( 'combobox_log' )
+ self.notebook = self.xml.get_widget( 'notebook' )
+ self.progressbar = self.xml.get_widget( 'progressbar')
+ self.button_connection = self.xml.get_widget( 'button_connection')
+ self.comboboxentry_server = self.xml.get_widget( 'comboboxentry_server' )
+ self.comboboxentry_entry1 = self.xml.get_widget( 'comboboxentry-entry1' )
+ self.button_resolve_errors = self.xml.get_widget( 'button_resolve_errors' )
+ self.spinbutton_log_limit = self.xml.get_widget( 'spinbutton_log_limit' )
+ # set up display tabs
+ self.init_vhost_list()
+ self.init_modules_list()
+ self.init_errors_list()
+ self.init_log_list()
+ self.status_icon = StatusIcon( self )
+
GuiUtils.style_as_tooltip( self.xml.get_widget( 'restart_apache_notice' ) )
- #GuiUtils.style_as_tooltip( self.xml.get_widget( 'unnormalized_notice' ) )
- #GuiUtils.style_as_tooltip( self.xml.get_widget( 'hbox_apache_config_error' ) )
-
- # start status update
- self.statusbar_server_status_context_id = self.statusbar_server_status.get_context_id("Apache Server Status")
- self.statusbar_server_status.push(self.statusbar_server_status_context_id, "Attempting to connect to server")
+
+ self.window_status_icons = [
+ # 0 - apache stopped
+ os.path.join( Configuration.GLADEPATH, 'icon_cadsoft_eagle.svg' )
+ # 1 - apache unreachable
+ , os.path.join( Configuration.GLADEPATH, 'icon_cadsoft_eagle_orange.svg' )
+ # 2 - apache started
+ , os.path.join( Configuration.GLADEPATH, 'icon_cadsoft_eagle_green.svg' )
+ ]
+
+ #Setup Bookmark Tree
+ #column = gtk.TreeViewColumn(('Icon'))
+ #column.set_spacing(4)
+ #cell = gtk.CellRendererPixbuf()
+ #column.pack_start(cell, expand=False)
+ #column.set_attributes(cell, pixbuf=0)
+ #self.treeview_bookmarks.append_column(column)
+
+ #column = gtk.TreeViewColumn(('Title'))
+ #column.set_spacing(4)
+ #cell = gtk.CellRendererText()
+ #column.pack_start(cell, True)
+ #column.set_attributes(cell, markup=1)
+ #self.treeview_bookmarks.append_column(column)
+
+ #store = gtk.ListStore(gtk.gdk.Pixbuf, str, int)
+ #self.treeview_bookmarks.set_model(store)
+
+ self.clear_server_information()
+
+ # if there is a localhost it will be set to current server
+ # so load it now
+ if self.core.current_server:
+ self.connect()
+
+ def start_pulse(self, text= ' '):
+ self.__pulse_text = text
+ self.__pulse_count = self.core.current_server.apache.count()
+ if not self.__pulse_flag:
+ self.__pulse_flag = True
+ self.__pulse()
+
+ def end_pulse(self):
+ self.__pulse_flag = False
+
+ @threaded
+ def __pulse(self):
+ while self.__pulse_flag == True:
+ gobject.idle_add(self.progressbar.pulse)
+ count = self.core.current_server.apache.count() - self.__pulse_count
+ text = self.__pulse_text
+ if count > 0: text += " (" + str(count) + " objects)"
+ gobject.idle_add(self.progressbar.set_text, text)
+ time.sleep(0.1)
+ gobject.idle_add(self.progressbar.set_fraction,0)
+ gobject.idle_add(self.progressbar.set_text,' ')
+
+ def clear_server_information(self):
+ self.vhosts_treeview.clear()
+ self.modules_treeview.clear()
+ self.treeview_errors.clear()
+ self.combobox_log.get_model().clear()
+ self.notebook.get_nth_page(0).hide()
+ self.menuitem_stop_apache.set_sensitive(False)
+ self.menuitem_start_apache.set_sensitive(False)
+ self.menuitem_restart_apache.set_sensitive(False)
+ self.text_view_log.get_buffer().set_text( "" )
+ self.text_view_log.set_editable(False)
+
+ self.comboboxentry_server.get_model().clear()
+ for server in self.core.servers:
+ self.comboboxentry_server.append_text(server)
+
+ def load_server_information(self, Force=False):
+ self.__load_server_information_pre(Force)
+
+ def __load_server_information_pre(self, Force=False):
+
+ self.clear_server_information()
+ self.notebook.set_sensitive(False)
+ self.status = 1
+ self.__load_server_information_thread(Force)
+ self.is_connecting( True, 'checking credentials...' )
+
+ @threaded
+ def __load_server_information_thread(self, Force=False):
+ print "START load_server_information"
+ # Do IO here, we need to do all IO in one big go so that we dont
+ # freeze the UI
+
+ result = self.core.current_server.command.test()
+
+ if not result:
+ gobject.idle_add(self.__load_server_information_fail)
+ return
+
+ gobject.idle_add(self.start_pulse,'loading web sites...')
+ self.core.current_server.apache.get_virtual_hosts( True, Force )
+
+ gobject.idle_add(self.start_pulse,'loading modules...')
+ self.core.current_server.apache.get_modules( True, Force )
+
+ gobject.idle_add(self.start_pulse,'loading log files...')
+ self.core.current_server.apache.get_logs( Force )
+
+ gobject.idle_add(self.start_pulse,'checking for errors...')
+ self.core.current_server.apache.get_errors( True )
+
+ gobject.idle_add(self.__load_server_information_post)
+
+ def __load_server_information_post(self):
+ # post load gtk actions
+
+ for file in self.core.current_server.apache.get_logs():
+ if file.endswith(".log"):
+ self.combobox_log.append_text(file)
+ self.combobox_log.set_active(0)
+
+ self.vhosts_treeview.load(self.core.current_server.apache.get_virtual_hosts())
+ self.modules_treeview.load(self.core.current_server.apache.get_modules())
+ errors = self.core.current_server.apache.get_errors()
+ self.treeview_errors.load(errors)
+ if len(errors) > 0:
+ self.notebook.get_nth_page(0).show()
+ self.notebook.set_current_page(0)
+ else:
+ self.notebook.get_nth_page(0).hide()
+
+ self.button_resolve_errors.set_sensitive(self.core.current_server.apache.get_fixable_error_count() > 0)
+ self.status = 0
self.update_server_status(True)
-
-
+ self.is_connecting( False )
+ self.core.save()
+
+ print "END load_server_information"
+
+ def __load_server_information_fail(self):
+
+ self.is_connecting( False )
+ self.notebook.set_sensitive(True)
+ self.clear_server_information()
+ self.end_pulse()
+ self.status = -1
+
+ #self.core.save()
+
+ print "FAIL load_server_information"
+
+
+ def on_button_connection_clicked(self, widget):
+
+ server = self.xml.get_widget( 'comboboxentry-entry1').get_text()
+ port = 22
+ username = ""
+ creditials_verified = False
+
+ if server in self.core.servers:
+ s = self.core.servers[server]
+ port = s.ssh_port
+ username = s.username
+ creditials_verified = s.creditials_verified
+
+ if not creditials_verified:
+ cd = ConnectionDetails()
+ cd.load(server, port, username)
+ server, port, username, password = cd.run()
+
+ if server in self.core.servers:
+ s = self.core.servers[server]
+ s.ssh_port = port
+ s.username = username
+ if password: s.password = password
+ self.core.current_server = s
+ else:
+ self.core.set_new_server(server, port, username, password)
+ else:
+ self.core.current_server = self.core.servers[server]
+
+ self.connect()
+
+ def connect(self):
+ self.comboboxentry_entry1.set_text( self.core.current_server.name )
+ self.load_server_information(True)
-
- self.menu_tools = self.xml.get_widget( 'menu_tools' )
- for plugin in self.plugin_manager.plugins:
- try:
- if plugin.is_enabled():
- menu_item = plugin.init_main_window(self)
- if menu_item != None:
- self.menu_tools.add(menu_item)
- menu_item.show()
- except Exception:
- traceback.print_exc(file=sys.stdout)
-
-
-
- # Add rich edit to log
- self.text_view_log = GuiUtils.new_apache_sourceview()
- self.xml.get_widget( 'scroll_window_log' ).add( self.text_view_log )
- self.text_view_log.show()
- combobox_log = self.xml.get_widget( 'combobox_log' )
- files = Shell.command.listdir("/var/log/apache2")
- for file in files:
- if file.endswith(".log"):
- combobox_log.append_text(file)
- combobox_log.set_active(0)
-
def on_button_open_log_clicked(self, widget):
- file = self.xml.get_widget( 'combobox_log' ).get_active_text()
- path = os.path.join("/var/log/apache2", file)
- text = Shell.command.read_file( path )
+ self.__load_log_file_pre()
+
+ def __load_log_file_pre(self):
+ file = self.combobox_log.get_active_text()
+ path = os.path.join( Configuration.LOG_PATH, file )
+ line_count = self.spinbutton_log_limit.get_value_as_int()
+ self.is_connecting( True, 'Loading log file ('+ path +')...' )
+ self.__load_log_file_thread(line_count, path)
+
+ @threaded
+ def __load_log_file_thread(self, line_count, path):
+ result, text, error = self.core.current_server.command.execute( ["tail", "-n", str(line_count), path] )
+ gobject.idle_add(self.__load_log_file_post,text, path)
+
+ def __load_log_file_post(self, text, path):
+ self.is_connecting( False )
self.text_view_log.get_buffer().set_text( text )
self.text_view_log.set_editable(False)
self.xml.get_widget( 'label_log_path').set_text( path )
- def refresh_config_test(self, focus=False):
- total = self.treeview_errors.load(self.apache, focus)
- notebook = self.xml.get_widget( 'notebook' )
- button_resolve_errors = self.xml.get_widget( 'button_resolve_errors' )
- page = notebook.get_nth_page(0)
- print "Errors status:", total
- if total > -1:
- page.show()
- if focus: notebook.set_current_page(0)
- else:
- page.hide()
-
- # focus tab if we have fixable errors
- if total > 0:
- button_resolve_errors.set_sensitive(True)
- else:
- button_resolve_errors.set_sensitive(False)
-
def add_new_vhost_menu_item(self, menu_item):
new_button = self.xml.get_widget( 'new_button')
menu = new_button.get_menu()
@@ -194,43 +343,80 @@
menu.add(menu_item)
menu.show_all()
+ def __update_server_status(self, image_apache_status, text, window_icon_id, stop, start, restart):
+ self.image_apache_status.set_from_stock(image_apache_status, gtk.ICON_SIZE_MENU)
+ self.label_server_status.set_text(text)
+ self.main_window.set_icon_from_file(self.window_status_icons[window_icon_id])
+ self.status_icon.tray.set_from_file(self.window_status_icons[window_icon_id])
+ self.menuitem_stop_apache.set_sensitive(stop)
+ self.status_icon.stopItem.set_sensitive(stop)
+ self.menuitem_start_apache.set_sensitive(start)
+ self.status_icon.startItem.set_sensitive(start)
+ self.menuitem_restart_apache.set_sensitive(restart)
+ self.status_icon.restartItem.set_sensitive(restart)
+
@threaded
def update_server_status(self, loop=False):
- window_status_icons = [
- # 0 - apache stopped
- os.path.join( Configuration.GLADEPATH, 'icon_cadsoft_eagle.svg' )
- # 1 - apache unreachable
- , os.path.join( Configuration.GLADEPATH, 'icon_cadsoft_eagle_orange.svg' ) #1
- # 2 - apache started
- , os.path.join( Configuration.GLADEPATH, 'icon_cadsoft_eagle_green.svg' ) #1
- ]
-
+
status_change_count = 0
- last_status = self.apache.get_status()
- while True:
- status = self.apache.get_status()
- text = "Apache is stopped"
- image = gtk.STOCK_NO
-
-
- if status == 1:
- text = "Warning can not contact apache"
- image = gtk.STOCK_DIALOG_WARNING
- if status == 2:
- text = "Apache is running"
- image = gtk.STOCK_YES
-
- # All gtk actions must be on main thread
- gtk.gdk.threads_enter()
- self.image_apache_status.set_from_stock(image, gtk.ICON_SIZE_MENU)
- self.statusbar_server_status.pop(self.statusbar_server_status_context_id)
- self.statusbar_server_status.push(self.statusbar_server_status_context_id, text)
- self.main_window.set_icon_from_file(window_status_icons[status])
- self.menuitem_stop_apache.set_sensitive(status == 2)
- self.menuitem_start_apache.set_sensitive(status == 0)
- self.menuitem_restart_apache.set_sensitive(status == 2)
- gtk.gdk.threads_leave()
+ last_status = 0
+
+ try:
+ last_status = self.core.current_server.apache.get_status()
+ except:
+ pass
+
+ while self.core.current_server:
+ if self.status == 0:
+ try:
+ status = 1
+ status = self.core.current_server.apache.get_status()
+ except:
+ pass
+
+ text = "Apache is stopped"
+ image = gtk.STOCK_NO
+ if status == 1:
+ text = "Warning can not contact apache"
+ image = gtk.STOCK_DIALOG_WARNING
+ if status == 2:
+ text = "Apache is running"
+ image = gtk.STOCK_YES
+
+ gobject.idle_add(
+ self.__update_server_status,
+ image,
+ text,
+ status,
+ status == 2,
+ status == 0,
+ status == 2
+ )
+ elif self.status == 1:
+
+ gobject.idle_add(
+ self.__update_server_status,
+ gtk.STOCK_CONNECT,
+ "Standby, establishing a connection...",
+ 1,
+ False,
+ False,
+ False
+ )
+
+ elif self.status == -1:
+
+ gobject.idle_add(
+ self.__update_server_status,
+ gtk.STOCK_DISCONNECT,
+ "Not connected",
+ 1,
+ False,
+ False,
+ False
+ )
+
if not loop:
break
@@ -245,7 +431,7 @@
def on_menuitem_stop_apache_activate(self, widget):
- self.apache.stop()
+ self.core.current_server.apache.stop()
self.update_server_status()
def on_button_hide_warning_clicked(self, widget):
@@ -256,48 +442,63 @@
self.please_restart()
return
if event.name == 'please_reload_lists':
- self.refresh_modules()
return
def browse_sites_available(self, widget):
- Desktop.open_dir( Configuration.SYSCONFDIR )
+ Desktop.open_dir( Configuration.SITES_AVAILABLE_DIR )
return
def new_button_clicked(self, widget):
new_vhost_window = VirtualHostWindow ( self )
new_vhost_window.load("")
- new_vhost_window.run()
- self.refresh_config_test()
+ vhost = new_vhost_window.run()
+ if vhost:
+ hosts = self.core.current_server.apache.get_virtual_hosts()
+ hosts[vhost.get_name()] = vhost
+ self.vhosts_treeview.load(hosts)
def edit_button_clicked(self, widget, notused = None, notused2 = None):
- name = self.vhosts_treeview.get_selected_line()
- self.open_edit_vhost_window( VirtualHostModel( name ) )
+ vhost = self.vhosts_treeview.get_selected_line()
+ clone = vhost.clone()
+ self.open_edit_vhost_window( clone )
-
def open_edit_vhost_window(self, vhost):
if not vhost.is_editable():
# Use generic editor instead
- gew = EditGenericWindow()
+ gew = EditGenericWindow(self.core)
gew.load( vhost.get_source_filename() )
- gew.run()
+ result = gew.run()
+ self.vhosts_treeview.load(self.core.current_server.apache.get_virtual_hosts())
+ if result:
+ self.please_restart()
+
else:
new_vhost_window = VirtualHostWindow ( self )
new_vhost_window.load( vhost )
- new_vhost_window.run()
- self.refresh_config_test()
+ vhost = new_vhost_window.run()
+ if vhost and vhost.changed:
+ hosts = self.core.current_server.apache.get_virtual_hosts()
+ hosts[vhost.get_name()] = vhost
+ self.vhosts_treeview.load(hosts)
+ self.please_restart()
def delete_button_clicked( self, widget ):
- name = self.vhosts_treeview.get_selected_line()
- if ( self.is_vhost_editable( name ) == False ): return False
- if ( name == None ): return False
- result = ConfirmationWindow.ask_confirmation(
- "You are about to delete the following domain: \n\n"+name+"\n\nData won't be recoverable. Proceed ?"
- ,'VirtualHost deletion' )
- if ( result != True ): return False
- site = VirtualHostModel( name )
- site.delete()
- self.vhosts_treeview.load()
+ vhost = self.vhosts_treeview.get_selected_line()
+ if not vhost: return False
+ if ( self.is_vhost_editable( vhost ) == False ): return False
+
+ md = gtk.MessageDialog(self.main_window, flags=0, type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_YES_NO, message_format="You are about to delete the following domain: \n\n"+vhost.get_server_name()+"\n\nData will not be recoverable. Are you sure ?")
+ result = md.run()
+ md.destroy()
+ if result != gtk.RESPONSE_YES:
+ return
+
+ # do the delete
+ hosts = self.core.current_server.apache.get_virtual_hosts()
+ del hosts[vhost.get_name()]
+ vhost.delete()
+
+ self.vhosts_treeview.load(hosts)
self.please_restart()
- self.refresh_config_test()
def edit_module_button_clicked(self, widget, notused = None, notused2 = None):
name = self.modules_treeview.get_selected_line()
@@ -306,14 +507,13 @@
module_window = ModuleWindow ( self )
module_window.load( name )
module_window.run()
- self.refresh_config_test()
def quit (self, widget):
print 'quitting'
gtk.main_quit()
exit()
- def create_vhost_list(self ):
+ def init_vhost_list(self ):
#print parent
#sw = gtk.ScrolledWindow()
sw = self.xml.get_widget( 'vhosts_scroll_box' )
@@ -329,23 +529,10 @@
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
sw.set_shadow_type(gtk.SHADOW_NONE)
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-
- # create denormalized vhosts.
- # We check for conf files only present in /etc/apache2/sites-enabled,
- # display them as a separate list and offer user to normalize them
- # moving them in /etc/apache2/sites-available and linking them back
- # from /etc/apache2/sites-enabled
-
- #denormalized_treeview = VhostsTreeView.DenormalizedVhostsTreeView()
- #self.denormalized_treeview = denormalized_treeview
-
- #denormalized_treeview.set_sensitive( False )
- #denormalized_treeview.show()
-
+
sw.show_all()
-
- def create_errors_list(self):
+ def init_errors_list(self):
self.treeview_errors = VhostsTreeView.ErrorsTreeView()
#treeview.selected_callback = self.row_selected
#treeview.connect_after("row-activated", self.edit_button_clicked )
@@ -353,10 +540,14 @@
self.xml.get_widget( 'viewport_errors' ).add(self.treeview_errors)
self.xml.get_widget( 'viewport_errors' ).show_all()
-
- #self.refresh_config_test()
+
+ def init_log_list(self):
+ # Add rich edit to log
+ self.text_view_log = GuiUtils.new_apache_sourceview()
+ self.xml.get_widget( 'scroll_window_log' ).add( self.text_view_log )
+ self.text_view_log.show()
- def create_modules_list(self ):
+ def init_modules_list(self ):
sw = self.xml.get_widget( 'modules_scroll_box' )
# create virtualhosts treeview
treeview = VhostsTreeView.ModulesTreeView()
@@ -364,49 +555,30 @@
treeview.selected_callback = self.module_row_selected
self.modules_treeview = treeview
self.xml.get_widget( 'modules_container' ).add(treeview)
- self.xml.get_widget( 'modules_container' ).reorder_child( treeview, 0)
sw.set_shadow_type(gtk.SHADOW_NONE)
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
sw.set_shadow_type(gtk.SHADOW_NONE)
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
sw.show_all()
- def refresh_vhosts ( self ):
- print "reloading vhosts.."
- self.vhosts_treeview.load()
- """def refresh_denormalized_vhosts (self):
- self.denormalized_treeview.load()
- #if ( len( self.denormalized_treeview.items ) > 0 ):
- #self.xml.get_widget( 'unnormalized_notice' ).show_all()
- #self.xml.get_widget( 'notebook' ).get_nth_page( 2 ).show()
- #else:
- #self.xml.get_widget( 'unnormalized_notice' ).hide_all()
- #self.xml.get_widget( 'notebook' ).get_nth_page( 2 ).hide()"""
- def refresh_modules (self):
- print "reloading modules.."
- self.modules_treeview.load()
- def refresh_lists (self, focus_error=False):
- self.refresh_vhosts()
- self.refresh_modules()
- self.refresh_config_test(focus_error)
-
def please_restart ( self ):
self.xml.get_widget( 'restart_apache_notice' ).show()
+
def restart_apache ( self, widget ):
- if not Shell.command.ask_password(): return
+ if not self.core.current_server.command.ask_password(): return
print "Restarting apache on user's request"
- self.apache.restart()
+ self.core.current_server.apache.restart()
self.update_server_status()
self.xml.get_widget( 'restart_apache_notice' ).hide()
- self.refresh_lists(True)
+
+ self.load_server_information()
def is_vhost_editable (self, name):
return name != 'default'
- def is_module_editable (self, name):
+ def is_module_editable (self, module):
editable = False
- if name:
- mod = self.modules_treeview.items[ name+".load" ]
- editable = mod.data[ 'configurable' ]
+ if module:
+ editable = module.data[ 'configurable' ]
return editable
def row_selected( self, widget ):
vhost = self.get_current_vhost()
@@ -439,33 +611,28 @@
open_module_doc(name)
def fix_vhosts(self, widget):
- if not Shell.command.ask_password(): return
- print "Attempting to fix virtualhosts"
- items = self.treeview_errors.get_items()
- for name in items:
- normalize_vhost( name )
- #since they were in the enabled, let's enabl'em again
- for name in items:
- if self.vhosts_treeview.items.has_key( name ):
- self.vhosts_treeview.items[name].toggle(True)
- #site.toggle(True)
- self.refresh_vhosts()
- #self.refresh_denormalized_vhosts()
- self.refresh_config_test()
+ if not self.core.current_server.command.ask_password(): return
+ self.core.current_server.apache.apply_fixable_errors()
+
+ errors = self.core.current_server.apache.get_errors(True)
+ self.treeview_errors.load(errors)
+ if len(errors) > 0:
+ self.notebook.get_nth_page(0).show()
+ self.notebook.set_current_page(0)
+ else:
+ self.notebook.get_nth_page(0).hide()
+
+ self.button_resolve_errors.set_sensitive(self.core.current_server.apache.get_fixable_error_count() > 0)
self.please_restart()
+
def get_current_vhost(self ):
- name = self.vhosts_treeview.get_selected_line()
- if ( name == None ): return None
-
- if self.vhosts_treeview.items.has_key( name ):
- return self.vhosts_treeview.items[ name ]
- else:
- return VirtualHostModel( name )
+ vhost = self.vhosts_treeview.get_selected_line()
+ return vhost
def surf_this(self, widget):
- name = self.vhosts_treeview.get_selected_line()
+ name = self.vhosts_treeview.get_selected_line().get_server_name()
if name == 'default':
- server_name = 'localhost'
+ server_name = self.core.current_server.name
else:
server_name = self.get_current_vhost().get_server_name()
@@ -477,8 +644,7 @@
if ( server_name ): Desktop.open_url( protocol+"://" + server_name )
def browse_this(self, widget):
document_root = self.get_current_vhost().config.DocumentRoot.value
- Desktop.open_dir( document_root )
-
+ Desktop.open_dir( self.core.current_server.get_nautilus_browse_string(document_root) )
def display_about (self, widget):
dialog = gtk.AboutDialog()
@@ -489,3 +655,26 @@
dialog.set_website('http://launchpad.net/rapache')
dialog.run()
dialog.destroy()
+
+ # status = True: shows progress bar, status = False: shows server entry
+ def is_connecting(self, status, text=""):
+ self.button_connection.set_sensitive( not status )
+ self.comboboxentry_server.set_sensitive( not status )
+ if status:
+ self.start_pulse(text)
+ self.progressbar.show()
+ self.comboboxentry_server.hide()
+ self.notebook.set_sensitive(False)
+ else:
+ self.end_pulse()
+ self.progressbar.hide()
+ self.comboboxentry_server.show()
+ self.notebook.set_sensitive(True)
+
+ def show(self):
+ self.main_window.show()
+
+ def hide(self):
+ self.main_window.hide()
+
+
=== added file 'RapacheGtk/Threads.py'
--- RapacheGtk/Threads.py 1970-01-01 00:00:00 +0000
+++ RapacheGtk/Threads.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,11 @@
+import threading
+import time
+
+# Define threaded attribute
+def threaded(f):
+ def wrapper(*args):
+
+ t = threading.Thread(target=f, args=args)
+ t.setDaemon(True) # wont keep app alive
+ t.start()
+ return wrapper
=== added file 'RapacheGtk/TrayIcon.py'
--- RapacheGtk/TrayIcon.py 1970-01-01 00:00:00 +0000
+++ RapacheGtk/TrayIcon.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+
+
+
+import os
+import gtk
+import RapacheGui
+
+
+class StatusIcon:
+ def __init__(self, main_window):
+ self.core = main_window.core
+ self.mainWindow = main_window
+ self.window_showing = True
+
+ self.tray = gtk.StatusIcon()
+ self.tray.set_tooltip( 'rapache' )
+ self.buildMenu()
+ self.tray.hide = lambda: self.tray.set_visible( False )
+ self.tray.show = lambda: self.tray.set_visible( True )
+
+ self.tray.connect( 'activate', self.on_activate )
+ self.tray.connect( 'popup-menu', self.on_popup_menu )
+
+ def buildMenu(self):
+ self.menu = gtk.Menu()
+
+ self.restartItem = gtk.MenuItem('Restart apache')
+ self.restartItem.connect('activate', self.on_restart)
+ self.menu.append(self.restartItem)
+
+ self.startItem = gtk.MenuItem('Start apache')
+ self.startItem.connect('activate', self.on_start)
+ self.menu.append(self.startItem)
+
+ self.stopItem = gtk.MenuItem('_Stop apache')
+ self.stopItem.connect('activate', self.on_stop)
+ self.menu.append(self.stopItem)
+
+ separator = gtk.SeparatorMenuItem()
+ self.menu.append(separator)
+
+ self.aboutItem = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
+ self.aboutItem.connect('activate', self.on_about)
+ self.menu.append(self.aboutItem)
+
+ self.quitItem = gtk.ImageMenuItem( gtk.STOCK_QUIT )
+ self.quitItem.connect('activate', self.on_quit)
+ self.menu.append(self.quitItem)
+
+
+ self.menu.show_all()
+
+ def on_quit(self, menuItem):
+ self.mainWindow.quit(menuItem)
+
+ def on_restart(self, menuItem):
+ self.core.current_server.apache.restart()
+
+ def on_stop(self, menuItem):
+ self.core.current_server.apache.stop()
+
+ def on_start(self, menuItem):
+ self.core.current_server.apache.start()
+
+ def on_about(self, menuItem):
+ self.mainWindow.display_about(menuItem)
+
+ def set_icon(self, icon):
+ self.tray.set_from_file(icon)
+
+ def on_activate( self, status_icon ):
+ self.showHide()
+
+ def on_popup_menu( self, status_icon, button, activate_time ):
+ self.menu.popup( None, None, None, button, activate_time )
+
+ def showHide(self, widget = None):
+ if self.window_showing == True:
+ self.mainWindow.hide()
+ self.window_showing = False
+ else:
+ self.mainWindow.show()
+ self.window_showing = True
=== modified file 'RapacheGtk/VhostsTreeView.py'
--- RapacheGtk/VhostsTreeView.py 2008-09-16 19:11:20 +0000
+++ RapacheGtk/VhostsTreeView.py 2010-05-16 23:57:26 +0000
@@ -23,6 +23,7 @@
from RapacheCore import Module
from RapacheCore import Configuration
from xml.sax import saxutils
+from RapacheGtk.Threads import threaded
class ConfFilesTreeView( CheckListView ):
def __init__ (self, *args, **kwargs):
@@ -42,24 +43,19 @@
class VhostsTreeView ( ConfFilesTreeView ):
def __init__ (self, *args, **kwargs):
super (VhostsTreeView, self).__init__ (*args, **kwargs)
- self.toggled_callback = self.__fixed_toggled
-
-
- def load(self):
- self.items = {}
+ self.toggled_callback = self.__toggle
+
+
+ def load(self, vhosts):
+ self.items = vhosts
site_template = "<b><big>%s</big></b>\n<small>DocumentRoot: %s</small>"
site_unparsable_template = "<b><big>%s</big></b>\n<small><i>Further information not available</i></small>"
lstore = self._reset_model()
data = []
- dirList=os.listdir( Configuration.SITES_AVAILABLE_DIR )
- dirList = [x for x in dirList if self._blacklisted( x ) == False ]
- for fname in dirList :
- site = VirtualHostModel( fname )
- if not site.is_new:
- self.items[ fname ] = site
-
+ icon_theme = gtk.icon_theme_get_default()
+
for idx in sorted( self.items ):
site = self.items[ idx ]
if ( site.parsable ):
@@ -70,74 +66,46 @@
iter = lstore.append()
favicon = site.get_icon()
- pixbuf = gtk.gdk.pixbuf_new_from_file( favicon )
+ if favicon:
+ pixbuf = gtk.gdk.pixbuf_new_from_file( favicon )
+ else:
+ pixbuf = icon_theme.lookup_icon("gtk-directory", 24, 0).load_icon()
lstore.set(iter,
COLUMN_FIXED, site.enabled,
COLUMN_ICON, pixbuf,
COLUMN_SEVERITY, site.get_name(),
- COLUMN_MARKUP, markup )
-
- def __fixed_toggled(self, cell, path, treeview):
- if not Shell.command.ask_password(): return
+ COLUMN_MARKUP, markup,
+ COLUMN_OBJECT, site )
+
+ def __toggle(self, cell, path, treeview):
+
# get toggled iter
model = treeview.get_model()
iter = model.get_iter((int(path),))
- fixed = model.get_value(iter, COLUMN_FIXED)
- name = model.get_value(iter, COLUMN_SEVERITY)
+ enabled = model.get_value(iter, COLUMN_FIXED)
+ vhost = model.get_value(iter, COLUMN_OBJECT)
- fixed = not fixed
- if fixed:
- Shell.command.sudo_execute ( [Configuration.APPPATH+'/hosts-manager', '-a',name])
- else :
- Shell.command.sudo_execute ( [Configuration.APPPATH+'/hosts-manager', '-r',name])
- # set new value
- site = VirtualHostModel( name )
- site.toggle( fixed )
- model.set(iter, COLUMN_FIXED, site.enabled )
- if ( site.changed ):
- self.raise_event( 'please_restart_apache' )
+ enabled = not enabled
+ if not vhost.apache.server.command.ask_password(): return
+ model.set(iter, COLUMN_FIXED, enabled )
+ self.__update_vhost_thread(vhost, enabled)
+
+ @threaded
+ def __update_vhost_thread(self, vhost, enabled):
+ try:
+ vhost.toggle( enabled )
+ except:
+ pass
+ gobject.idle_add(self.__update_vhost_post, vhost)
+
+ def __update_vhost_post(self, vhost):
+ if ( vhost.changed ):
+ self.raise_event( 'please_restart_apache', vhost )
+ self.raise_event( 'please_reload_lists', {}, True )
+
gobject.type_register (VhostsTreeView)
-"""
-class DenormalizedVhostsTreeView ( ConfFilesTreeView ):
- def __init__ (self, *args, **kwargs):
- super (DenormalizedVhostsTreeView, self).__init__ (*args, **kwargs)
- #print self.column_checkbox, self.column_description, self.column_icon
- self.column_checkbox.set_visible( False )
- self.column_icon.get_cell_renderers()[0].set_property( 'stock-id', gtk.STOCK_DIALOG_WARNING )
- def load(self):
- self.items = {}
- site_template = "<b><big>%s</big></b>"
- lstore = self._reset_model()
-
- data = []
- dirList=os.listdir( Configuration.SITES_ENABLED_DIR )
- dirList = [x for x in dirList if self._blacklisted( x ) == False ]
- dirList = [x for x in dirList if is_denormalized_vhost( x ) == False ]
-
- self.items = {}
- for fname in dirList :
- site = VirtualHostModel( fname )
- self.items[ fname ] = site
- site = None
- for idx in sorted( self.items ):
- site = self.items[ idx ]
- normalizable = not is_not_normalizable(site.get_name())
- markup = site_template % site.get_name()
- if ( normalizable == False ):
- markup = markup + " CANNOT FIX"
- iter = lstore.append()
-
- lstore.set(iter,
- COLUMN_FIXED, normalizable,
- COLUMN_SEVERITY, site.get_name(),
- COLUMN_MARKUP, markup
- )
-
- def toggled_callback(self, *args, **kwargs):
- pass
-gobject.type_register (DenormalizedVhostsTreeView )
-"""
+
class ModulesTreeView ( ConfFilesTreeView ):
def __init__ (self, *args, **kwargs):
super (ModulesTreeView, self).__init__ (*args, **kwargs)
@@ -146,35 +114,25 @@
pixbuf = gtk.gdk.pixbuf_new_from_file( icon_file_name )
self.column_icon.get_cell_renderers()[0].set_property('pixbuf', pixbuf)
- self.toggled_callback = self.__fixed_toggled
+ self.toggled_callback = self.__toggle
self.selected_callback = self.__selected
self.column_description.get_cell_renderers()[0].set_property('wrap-mode', gtk.WRAP_WORD)
self.column_description.get_cell_renderers()[0].set_property('wrap-width', 400)
def __selected(self, *args, **kwargs ):
print "MODULE NAME:", self.get_selected_line()
print "DEPENDANTS: ", Module.get_module_dependants(self.get_selected_line(), self.items)
- def load(self):
- self.items = {}
+
+
+ def load(self, modules):
+ self.items = modules
mod_template = "<b><big>%s</big></b>"
mod_unparsable_template = "<b><big>%s</big></b>\n<small><i>Further information not available</i></small>"
lstore = self._reset_model()
data = []
-
- """dirList=os.listdir( Configuration.MODS_AVAILABLE_DIR )
- dirList = [x for x in dirList if self._blacklisted( x ) == False ]
- for fname in dirList :
- mod = Module.ModuleModel( fname )
- try:
- mod.load()
- except "VhostUnparsable":
- pass
- self.items[ fname ] = mod
- mod = None
- """
- self.items = Module.module_list()
-
- for idx in sorted( self.items ):
- mod = self.items[ idx ]
+ keys = self.items.keys()
+ keys.sort()
+ for key in keys:
+ mod = modules[key]
if ( mod.parsable ):
markup = mod_template \
% ( mod.data['name'] ) #, mod.data[ 'DocumentRoot' ] )
@@ -190,28 +148,44 @@
lstore.set(iter,
COLUMN_FIXED, mod.data['enabled'],
COLUMN_SEVERITY, mod.data['name'],
- COLUMN_MARKUP, markup )
+ COLUMN_MARKUP, markup,
+ COLUMN_OBJECT, mod )
+<<<<<<< TREE
def __fixed_toggled(self, cell, path, treeview):
if not Shell.command.ask_password(): return
+=======
+ def __toggle(self, cell, path, treeview):
+
+>>>>>>> MERGE-SOURCE
# get toggled iter
model = treeview.get_model()
iter = model.get_iter((int(path),))
- fixed = model.get_value(iter, COLUMN_FIXED)
- name = model.get_value(iter, COLUMN_SEVERITY)
- fixed = not fixed
- # set new value
- mod = Module.ModuleModel( name )
- mod.toggle( fixed )
- model.set(iter, COLUMN_FIXED, mod.data['enabled'] )
- if ( mod.changed ):
- self.raise_event( 'please_restart_apache' )
+ enabled = model.get_value(iter, COLUMN_FIXED)
+ mod = model.get_value(iter, COLUMN_OBJECT)
+ enabled = not enabled
+
+ if not mod.apache.server.command.ask_password(): return
+ model.set(iter, COLUMN_FIXED, enabled )
+ self.__update_module_thread(mod, enabled)
+
+ @threaded
+ def __update_module_thread(self, module, enabled):
+ try:
+ module.toggle( enabled )
+ except:
+ pass
+ gobject.idle_add(self.__update_module_post, module)
+
+ def __update_module_post(self, module):
+ if ( module.changed ):
+ self.raise_event( 'please_restart_apache', module )
self.raise_event( 'please_reload_lists', {}, True )
+
gobject.type_register ( ModulesTreeView )
-
class ErrorsTreeView ( ConfFilesTreeView ):
def __init__ (self, *args, **kwargs):
super (ErrorsTreeView, self).__init__ (*args, **kwargs)
@@ -220,109 +194,22 @@
self.column_description.get_cell_renderers()[0].set_property('wrap-width', 400)
self.column_checkbox.get_cell_renderers()[0].set_property( 'activatable', False )
- def load(self, apache, test_apache=False):
- self.items = {}
- site_template = "<b><big>%s</big></b>"
- lstore = self._reset_model()
- res, text = True, ""
-
- # -1 = nothing to fix
- # 0 = nothing auto-fixable
- # 1 = something to be done
- returncode = -1
- if test_apache:
- res, text = apache.test_config()
- text = saxutils.escape(text)
- if not res:
- returncode = 0
- iter = lstore.append()
- markup = site_template % "Apache Config Error"
-
- pixbuf = self.render_icon(gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_LARGE_TOOLBAR)
-
- lstore.set(iter,
- COLUMN_ICON, pixbuf,
- COLUMN_FIXED, False,
- COLUMN_SEVERITY, "Apache Config Error",
- COLUMN_MARKUP, markup + "\n" + text +"\n<small><i>You may need to resolve this error to restart apache</i></small>"
- )
-
- self._add_ssl_port_error_vhosts()
- fixable_items = self._add_denormalized_vhosts()
- return max( returncode, fixable_items )
-
- def _add_ssl_port_error_vhosts( self ):
- fixable_items = 0
- mod = Module.ModuleModel( "ssl" )
- if mod.data['enabled']:
- site_template = "<b><big>%s</big></b>"
- lstore = self.get_model()
- data = []
- dirList=os.listdir( Configuration.SITES_ENABLED_DIR )
- dirList = [x for x in dirList if self._blacklisted( x ) == False ]
-
-
- bad_items = {}
-
- for fname in dirList :
- site = VirtualHostModel( fname )
- if site.enabled and not site.has_port():
- bad_items[ fname ] = site
- site = None
- for idx in sorted( bad_items ):
- site = bad_items[ idx ]
- fixable = False
- markup = site_template % site.get_name()
- markup = markup + " CANNOT FIX"
-
- iter = lstore.append()
- pixbuf = self.render_icon(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_LARGE_TOOLBAR)
- lstore.set(iter,
- COLUMN_ICON, pixbuf,
- COLUMN_FIXED, False,
- COLUMN_SEVERITY, site.get_name(),
- COLUMN_MARKUP, markup + "\nThe virtual host does not have a port number and you have enabled ssl\n<small><i>You must add a port number (80)</i>.</small>"
- )
- if not len(lstore): return -1
- return fixable_items
-
-
- def _add_denormalized_vhosts( self ):
-
- site_template = "<b><big>%s</big></b>"
- lstore = self.get_model()
- data = []
- dirList=os.listdir( Configuration.SITES_ENABLED_DIR )
- dirList = [x for x in dirList if self._blacklisted( x ) == False ]
- dirList = [x for x in dirList if is_denormalized_vhost( x ) == False ]
-
- fixable_items = 0
-
- for fname in dirList :
- site = VirtualHostModel( fname )
- self.items[ fname ] = site
- site = None
- for idx in sorted( self.items ):
- site = self.items[ idx ]
- normalizable = not is_not_normalizable(site.get_name())
- markup = site_template % site.get_name()
- if ( normalizable == False ):
- markup = markup + " CANNOT FIX"
- else:
- fixable_items += 1
+ def load(self, errors):
+ self.items = errors
+ lstore = self._reset_model()
+
+ for error in errors:
iter = lstore.append()
pixbuf = self.render_icon(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_LARGE_TOOLBAR)
lstore.set(iter,
COLUMN_ICON, pixbuf,
- COLUMN_FIXED, normalizable,
- COLUMN_SEVERITY, site.get_name(),
- COLUMN_MARKUP, markup + "\nThe virtual host file is only present inside /etc/apache/sites-enabled.\n<small><i>You must normalize in order to manage this host</i>.</small>"
+ COLUMN_FIXED, error.fixable,
+ COLUMN_SEVERITY, error.title,
+ COLUMN_MARKUP, "<b>" + error.title +"</b>\n" + error.description
)
-
if not len(lstore): return -1
- return fixable_items
-
-
+ return errors
+
def toggled_callback(self, *args, **kwargs):
pass
#gobject.type_register (DenormalizedVhostsTreeView )
=== modified file 'RapacheGtk/VirtualHostGui.py'
--- RapacheGtk/VirtualHostGui.py 2008-09-15 02:26:42 +0000
+++ RapacheGtk/VirtualHostGui.py 2010-05-16 23:57:26 +0000
@@ -60,7 +60,7 @@
def __init__ ( self, parent = None):
-
+ self.__result = None
self.parent = parent
self.plugins = []
self.vhost = None
@@ -74,7 +74,6 @@
self.button_location = wtree.get_widget("button_location")
self.treeview_domain = wtree.get_widget("treeview_domain")
self.checkbutton_hosts = wtree.get_widget("checkbutton_hosts")
- self.label_hosts = wtree.get_widget("label_hosts")
self.toolbutton_domain_add = wtree.get_widget("toolbutton_domain_add")
self.toolbutton_domain_edit = wtree.get_widget("toolbutton_domain_edit")
self.toolbutton_domain_delete = wtree.get_widget("toolbutton_domain_delete")
@@ -149,17 +148,7 @@
store.append((icon_theme.lookup_icon("applications-internet", 24, 0).load_icon(), "Domain", 0))
# init enabled plugins
- for plugin in self.parent.plugin_manager.plugins:
- try:
- if plugin.is_enabled():
- content, title, pixbuf = plugin.init_vhost_properties()
- tab_count = self.notebook.get_n_pages() - 1
- plugin._tab_number = self.notebook.insert_page(content, gtk.Label(title), tab_count)
- store.append((pixbuf, title, tab_count))
- content.show()
- self.plugins.append(plugin)
- except Exception:
- traceback.print_exc(file=sys.stdout)
+ self.parent.core.plugin_manager.init_vhost_properties( store, gtk.Label, self.notebook )
store.append((icon_theme.load_icon(gtk.STOCK_EDIT, 24, 0), "Definition File", self.notebook.get_n_pages() - 1))
@@ -174,7 +163,7 @@
self.button_save.add_accelerator("clicked", self.accel_group, 13, 0, 0)
- self.vhost = VirtualHostModel( "")
+ self.vhost = VirtualHostModel("", self.parent.core.current_server.apache)
def on_treeview_menu_cursor_changed(self, widget):
model, iter = self.treeview_menu.get_selection().get_selected()
@@ -255,6 +244,7 @@
self.window.show()
gtk.main()
+ return self.__result
def load (self, vhost ):
if vhost:
@@ -271,7 +261,7 @@
self.label_path.set_text( self.vhost.get_source_filename() )
self.on_entry_domain_changed()
-
+
def save_edit_tab(self):
#print "Save edit tab"
buf = self.text_view_vhost_source.get_buffer()
@@ -355,27 +345,10 @@
return
def update_plugin_tab(self, tab):
- #print "Update plugin : ", tab
- if self.plugins:
- for plugin in self.plugins:
- try:
- if plugin.is_enabled() and plugin._tab_number == tab:
- plugin.load_vhost_properties(self.vhost)
- except Exception:
- traceback.print_exc(file=sys.stdout)
+ self.parent.core.plugin_manager.load_vhost_properties( self.vhost, tab )
def save_plugin_tab(self, tab):
- result = True
- error = ""
- #print "Save plugin : ", tab
- if self.plugins:
- for plugin in self.plugins:
- try:
- if plugin.is_enabled() and plugin._tab_number == tab:
- result, error = plugin.update_vhost_properties(self.vhost)
- except Exception:
- traceback.print_exc(file=sys.stdout)
- return result, error
+ return self.parent.core.plugin_manager.update_vhost_properties(self.vhost, tab )
def get_domain (self):
return self.entry_domain.get_text().strip()
@@ -416,7 +389,7 @@
location = self.entry_location.get_text().strip()
- while not Shell.command.exists(location):
+ while not self.parent.core.current_server.command.exists(location):
location = os.path.abspath(os.path.join(location, os.path.pardir))
if not location:
@@ -490,40 +463,24 @@
self.show_error ( message )
except Exception:
traceback.print_exc(file=sys.stdout)
-
-
- is_new = self.vhost.is_new
-
- self.vhost.hack_hosts = self.checkbutton_hosts.get_active()
-
+
# save over buffer content
self.vhost.save()
- #update /etc/hosts only if it's a new vhost
-
- if is_new:
- if self.hack_hosts:
- #update servername
- if self.vhost.config.ServerName and self.vhost.config.ServerName.value:
- Shell.command.sudo_execute ( [os.path.join(Configuration.APPPATH, "hosts-manager"), '-a', self.vhost.config.ServerName.value ] )
- #add an entry for each host
- if self.vhost.config.ServerAlias:
- for alias in self.vhost.config.ServerAlias:
- Shell.command.sudo_execute ( [os.path.join(Configuration.APPPATH, 'hosts-manager'), '-a', alias ])
-
# check apache config
- returncode, error = self.parent.apache.test_config()
+ returncode, error = self.parent.core.current_server.apache.test_config()
if not returncode:
error = error.strip()
- md = gtk.MessageDialog(self.window, flags=0, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK_CANCEL, message_format="Changes have been saved, but an error has been detected: \n\n"+error + "\n\nAre you sure you want to continue? Apache may not start until all errors are resolved.")
+ md = gtk.MessageDialog(self.window, flags=0, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK_CANCEL, message_format=error + "\n\nAre you sure you want to continue, apache may not start until all errors are resolved")
result = md.run()
md.destroy()
if result != gtk.RESPONSE_OK:
return
#self.parent.create_vhost_list()
- self.parent.refresh_vhosts()
- self.parent.please_restart()
+ #self.parent.refresh_vhosts()
+ #self.parent.please_restart()
+ self.__result = self.vhost
self.window.destroy()
def on_button_cancel_clicked(self, widget):
=== modified file 'plugins/advanced/plugin.py'
--- plugins/advanced/plugin.py 2008-09-09 04:18:04 +0000
+++ plugins/advanced/plugin.py 2010-05-16 23:57:26 +0000
@@ -33,9 +33,10 @@
class AdvancedVhostPlugin(PluginBaseObject):
- def __init__(self, path):
+ def __init__(self, core, path):
# The path to the plugin
+ self.core = core
self.path = path
# module this plugin works with
@@ -201,6 +202,6 @@
result = not server_admin or re.match("^[a-zA-Z0-9._%-]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", server_admin)
return result, "Server Admin is not a valid email address"
-def register( path ):
- return AdvancedVhostPlugin( path )
+def register( core, path ):
+ return AdvancedVhostPlugin( core, path )
=== modified file 'plugins/basic_authentication/htpasswd.py'
--- plugins/basic_authentication/htpasswd.py 2008-08-27 04:10:17 +0000
+++ plugins/basic_authentication/htpasswd.py 2010-05-16 23:57:26 +0000
@@ -70,15 +70,16 @@
self.loaded = False
def load(self, content):
- """Read the htpasswd file into memory."""
- lines = content.split("\n")
- self.entries = []
- for line in lines:
- if line.strip():
- username, pwhash = line.split(':')
- entry = [username, pwhash.rstrip()]
- self.entries.append(entry)
- self.loaded = True
+ if content:
+ """Read the htpasswd file into memory."""
+ lines = content.split("\n")
+ self.entries = []
+ for line in lines:
+ if line.strip():
+ username, pwhash = line.split(':')
+ entry = [username, pwhash.rstrip()]
+ self.entries.append(entry)
+ self.loaded = True
def save(self):
"""Write the htpasswd file to disk"""
=== modified file 'plugins/basic_authentication/plugin.py'
--- plugins/basic_authentication/plugin.py 2008-09-09 04:18:04 +0000
+++ plugins/basic_authentication/plugin.py 2010-05-16 23:57:26 +0000
@@ -16,7 +16,6 @@
import os
from RapacheCore.PluginBase import PluginBaseObject
-from RapacheCore import Shell
from htpasswd import Htpasswd
from user_credentials import UserCredentials
try:
@@ -32,10 +31,11 @@
class BasicAuthenticationPlugin(PluginBaseObject):
- def __init__(self, path):
+ def __init__(self, core, plugin_path):
# The path to the plugin
- self.path = path
+ self.path = plugin_path
+ self.core = core
# module this plugin works with
self.module = "auth_basic"
@@ -163,7 +163,7 @@
self.treeview_users.append_column(column)
self.entry_location.set_text(self.default_location)
- self.users.load(Shell.command.read_file(self.default_location))
+ self.users.load(self.core.current_server.command.read_file(self.default_location))
self.entry_warning_message.set_text("Enter your password")
@@ -190,7 +190,7 @@
if d.AuthUserFile:
if d.AuthUserFile.value != self.entry_location.get_text():
self.entry_location.set_text(d.AuthUserFile.value)
- content = Shell.command.read_file(self.entry_location.get_text())
+ content = self.core.current_server.command.read_file(self.entry_location.get_text())
if content:
self.users.load( content )
@@ -245,11 +245,11 @@
# Perform action on vhost properties save
def save_vhost_properties(self, vhost):
- Shell.command.write_file( self.entry_location.get_text(), self.users.save())
+ self.core.current_server.command.write_file( self.entry_location.get_text(), self.users.save())
return True, None
-def register( path ):
- return BasicAuthenticationPlugin( path )
+def register( core, path ):
+ return BasicAuthenticationPlugin( core, path )
=== added directory 'plugins/error_document'
=== added file 'plugins/error_document/__init__.py'
--- plugins/error_document/__init__.py 1970-01-01 00:00:00 +0000
+++ plugins/error_document/__init__.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,1 @@
+
=== added file 'plugins/error_document/error_codes.py'
--- plugins/error_document/error_codes.py 1970-01-01 00:00:00 +0000
+++ plugins/error_document/error_codes.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,52 @@
+error_codes = {
+ 100 : "Continue",
+ 101 : "Switching Protocols",
+ 102 : "Processing",
+ 200 : "OK",
+ 201 : "Created",
+ 202 : "Accepted",
+ 203 : "Non-Authoritative Information",
+ 204 : "No Content",
+ 205 : "Reset Content",
+ 206 : "Partial Content",
+ 207 : "Multi-Status",
+ 300 : "Multiple Choices",
+ 301 : "Moved Permanently",
+ 302 : "Found",
+ 303 : "See Other",
+ 304 : "Not Modified",
+ 305 : "Use Proxy",
+ 307 : "Temporary Redirect",
+ 400 : "Bad Request",
+ 401 : "Authorization Required",
+ 402 : "Payment Required",
+ 403 : "Forbidden",
+ 404 : "Not Found",
+ 405 : "Method Not Allowed",
+ 406 : "Not Acceptable",
+ 407 : "Proxy Authentication Required",
+ 408 : "Request Time-out",
+ 409 : "Conflict",
+ 410 : "Gone",
+ 411 : "Length Required",
+ 412 : "Precondition Failed",
+ 413 : "Request Entity Too Large",
+ 414 : "Request-URI Too Large",
+ 415 : "Unsupported Media Type",
+ 416 : "Requested Range Not Satisfiable",
+ 417 : "Expectation Failed",
+ 422 : "Unprocessable Entity",
+ 423 : "Locked",
+ 424 : "Failed Dependency",
+ 425 : "No code",
+ 426 : "Upgrade Required",
+ 500 : "Internal Server Error",
+ 501 : "Method Not Implemented",
+ 502 : "Bad Gateway",
+ 503 : "Service Temporarily Unavailable",
+ 504 : "Gateway Time-out",
+ 505 : "HTTP Version Not Supported",
+ 506 : "Variant Also Negotiates",
+ 507 : "Insufficient Storage",
+ 510 : "Not Extended"
+ }
=== added file 'plugins/error_document/error_document.glade'
--- plugins/error_document/error_document.glade 1970-01-01 00:00:00 +0000
+++ plugins/error_document/error_document.glade 2010-05-16 23:57:26 +0000
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Thu Sep 25 22:42:52 2008 -->
+<glade-interface>
+ <widget class="GtkWindow" id="window1">
+ <child>
+ <widget class="GtkHBox" id="hbox_error_document">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkViewport" id="viewport1">
+ <property name="visible">True</property>
+ <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="hbox6">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Error Documents</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow_error_document">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <widget class="GtkTreeView" id="treeview_error_document">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="enable_search">False</property>
+ <property name="search_column">5</property>
+ <property name="enable_grid_lines">GTK_TREE_VIEW_GRID_LINES_BOTH</property>
+ <property name="enable_tree_lines">True</property>
+ <signal name="row_activated" handler="on_treeview_error_document_row_activated"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLinkButton" id="linkbutton1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">documentation</property>
+ <property name="relief">GTK_RELIEF_NONE</property>
+ <property name="response_id">0</property>
+ <property name="uri">http://glade.gnome.org</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">8</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
=== added file 'plugins/error_document/plugin.py'
--- plugins/error_document/plugin.py 1970-01-01 00:00:00 +0000
+++ plugins/error_document/plugin.py 2010-05-16 23:57:26 +0000
@@ -0,0 +1,221 @@
+# Rapache - Apache Configuration Tool
+# Copyright (C) 2008 Stefano Forenza, Jason Taylor, Emanuele Gentili
+#
+# This program 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.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+from RapacheCore.PluginBase import PluginBaseObject
+try:
+ import pygtk
+ pygtk.require("2.0")
+except:
+ pass
+try:
+ import gtk
+ import gtk.glade
+except:
+ sys.exit(1)
+
+
+error_codes = {
+ 100 : "Continue",
+ 101 : "Switching Protocols",
+ 102 : "Processing",
+ 200 : "OK",
+ 201 : "Created",
+ 202 : "Accepted",
+ 203 : "Non-Authoritative Information",
+ 204 : "No Content",
+ 205 : "Reset Content",
+ 206 : "Partial Content",
+ 207 : "Multi-Status",
+ 300 : "Multiple Choices",
+ 301 : "Moved Permanently",
+ 302 : "Found",
+ 303 : "See Other",
+ 304 : "Not Modified",
+ 305 : "Use Proxy",
+ 307 : "Temporary Redirect",
+ 400 : "Bad Request",
+ 401 : "Authorization Required",
+ 402 : "Payment Required",
+ 403 : "Forbidden",
+ 404 : "Not Found",
+ 405 : "Method Not Allowed",
+ 406 : "Not Acceptable",
+ 407 : "Proxy Authentication Required",
+ 408 : "Request Time-out",
+ 409 : "Conflict",
+ 410 : "Gone",
+ 411 : "Length Required",
+ 412 : "Precondition Failed",
+ 413 : "Request Entity Too Large",
+ 414 : "Request-URI Too Large",
+ 415 : "Unsupported Media Type",
+ 416 : "Requested Range Not Satisfiable",
+ 417 : "Expectation Failed",
+ 422 : "Unprocessable Entity",
+ 423 : "Locked",
+ 424 : "Failed Dependency",
+ 425 : "No code",
+ 426 : "Upgrade Required",
+ 500 : "Internal Server Error",
+ 501 : "Method Not Implemented",
+ 502 : "Bad Gateway",
+ 503 : "Service Temporarily Unavailable",
+ 504 : "Gateway Time-out",
+ 505 : "HTTP Version Not Supported",
+ 506 : "Variant Also Negotiates",
+ 507 : "Insufficient Storage",
+ 510 : "Not Extended"
+ }
+
+class ErrorDocumentPlugin(PluginBaseObject):
+
+ def __init__(self, core, path):
+
+ # The path to the plugin
+ self.path = path
+
+ # module this plugin works with
+ self.module = ""
+
+ def update_tree(self):
+ store = gtk.ListStore(str, str)
+ self.treeview_error_document.set_model(store)
+ for doc in self.documents:
+ store.append((doc,doc))
+
+
+ def init_vhost_properties(self):
+
+ # Get glade file XML
+ f = open( os.path.join(self.path, "error_document.glade") ,"r")
+ self.glade_vhost_xml = f.read()
+ f.close()
+
+ # Remember you will need to recreate tree everytime the window loads
+ wtree = gtk.glade.xml_new_from_buffer(self.glade_vhost_xml, len(self.glade_vhost_xml), "hbox_error_document")
+ self.treeview_error_document = wtree.get_widget("treeview_error_document")
+ self.hbox_error_document = wtree.get_widget("hbox_error_document")
+
+
+ # Setup tree
+ column = gtk.TreeViewColumn(('Code'))
+ column.set_spacing(4)
+ cell = gtk.CellRendererText()
+ column.pack_start(cell, expand = False)
+ column.set_attributes(cell, markup=0)
+ self.treeview_error_document.append_column(column)
+
+ column = gtk.TreeViewColumn(('Description'))
+ column.set_spacing(4)
+ cell = gtk.CellRendererText()
+ column.pack_start(cell, expand = False)
+ column.set_attributes(cell, markup=1)
+ self.treeview_error_document.append_column(column)
+
+ column = gtk.TreeViewColumn(('Response'))
+ column.set_spacing(4)
+ cell = gtk.CellRendererText()
+ cell.set_property('editable', True)
+ #cell.connect('editing-started', self.cell_edit_start)
+ cell.connect('edited', self.cell_edited)
+ column.pack_start(cell, True)
+ column.set_attributes(cell, markup=2)
+ self.treeview_error_document.append_column(column)
+
+ signals = {
+ "on_treeview_error_document_row_activated" : self.on_treeview_error_document_row_activated
+ }
+ wtree.signal_autoconnect(signals)
+
+ icon_theme = gtk.icon_theme_get_default()
+ pixbuf = icon_theme.load_icon(gtk.STOCK_DIALOG_ERROR, 24, 0)
+
+ return self.hbox_error_document, "Error Documents", pixbuf
+
+ def cell_edit_start(self, editable, a, path):
+ print path
+ print a
+ if path == "0":
+ editable.stop_editing(True)
+
+ def on_treeview_error_document_row_activated(self, widget, a, b):
+ print widget
+ print a
+ print b
+
+
+ def cell_edited(self, cell, path, new_text):
+ store = self.treeview_error_document.get_model()
+ iter = store.get_iter(path)
+ store.set_value(iter, 2, new_text)
+
+ code = int(store.get_value(iter, 0))
+
+ return
+
+ # Customise the vhost properties window
+ def load_vhost_properties(self, vhost):
+
+ store = gtk.TreeStore(str, str, str)
+ self.treeview_error_document.set_model(store)
+ common_errors = [400, 403, 404, 500]
+ keys = error_codes.keys()
+ keys.sort()
+
+ active_errors = {}
+
+ for ed in vhost.config.ErrorDocument:
+ active_errors[ int(ed.opts[0]) ] = ed.opts[1]
+
+ for key in keys:
+ if key in common_errors:
+ value = ""
+ if active_errors.has_key( key ):
+ value = active_errors[key]
+ store.append(None, ( str(key) , "<b>" + error_codes[key] +"</b>", value))
+
+ for key in keys:
+ if not key in common_errors:
+ value = ""
+ if active_errors.has_key( key ):
+ value = active_errors[key]
+ store.append(None, ( str(key), error_codes[key], value))
+
+ return
+
+ # Perform action on vhost properties save
+ def update_vhost_properties(self, vhost):
+ store = self.treeview_error_document.get_model()
+
+ del vhost.config.ErrorDocument
+
+ itr = store.get_iter_first()
+ while itr:
+
+ code = int(store.get_value(itr, 0))
+ value = store.get_value(itr, 2)
+
+ if value.strip():
+ vhost.config.ErrorDocument.search(code).opts=[code, value]
+
+ itr = store.iter_next(itr)
+
+ return True, None
+
+def register( core, path ):
+ return ErrorDocumentPlugin( core, path )
+
=== modified file 'plugins/ssl/certificate_request.py'
--- plugins/ssl/certificate_request.py 2008-09-09 04:18:04 +0000
+++ plugins/ssl/certificate_request.py 2010-05-16 23:57:26 +0000
@@ -52,14 +52,15 @@
from RapacheCore.Module import *
from RapacheGtk import GuiUtils
import RapacheGtk.DesktopEnvironment as Desktop
-import RapacheCore.Shell
+
from text_display import TextDisplayWindow
class CertificateRequestWindow:
- def __init__(self, path):
-
+ def __init__(self, core, path):
+
+ self.core = core
# The path to the plugin
self.glade_path = path
@@ -122,12 +123,12 @@
pkey = crypto.PKey()
print "Private key : " + privatekey_path
- if not Shell.command.sudo_exists(privatekey_path):
+ if not self.core.current_server.command.sudo_exists(privatekey_path):
pkey.generate_key(crypto.TYPE_RSA, 1024)
- Shell.command.write_file( privatekey_path, crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey), False)
+ self.core.current_server.command.write_file( privatekey_path, crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey), False)
else:
- pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, Shell.command.sudo_read_file(privatekey_path))
+ pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, self.core.current_server.command.sudo_read_file(privatekey_path))
req = crypto.X509Req()
subj = req.get_subject()
@@ -145,7 +146,7 @@
req.set_pubkey(pkey)
req.sign(pkey, "md5")
print "Created cert " + certreq_path
- Shell.command.write_file( certreq_path, crypto.dump_certificate_request(crypto.FILETYPE_PEM, req))
+ self.core.current_server.command.write_file( certreq_path, crypto.dump_certificate_request(crypto.FILETYPE_PEM, req))
if self.checkbutton_self_sign.get_active():
@@ -158,11 +159,11 @@
cert.set_pubkey(req.get_pubkey())
cert.sign(pkey, "md5")
print "Created cert " + cert_path
- Shell.command.write_file( cert_path, crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
+ self.core.current_server.command.write_file( cert_path, crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
self.cert = cert_path
else:
- tdw = TextDisplayWindow(self.glade_path)
+ tdw = TextDisplayWindow(self.core, self.glade_path)
help_array = []
=== modified file 'plugins/ssl/plugin.py'
--- plugins/ssl/plugin.py 2008-09-15 02:50:33 +0000
+++ plugins/ssl/plugin.py 2010-05-16 23:57:26 +0000
@@ -17,7 +17,6 @@
import os
from RapacheCore.PluginBase import PluginBaseObject
from certificate_request import CertificateRequestWindow
-from RapacheCore import Shell
from text_display import TextDisplayWindow
from OpenSSL import crypto
import subprocess
@@ -48,9 +47,10 @@
"""
class AdvancedVhostPlugin(PluginBaseObject):
- def __init__(self, path):
+ def __init__(self, core, path):
# The path to the plugin
+ self.core = core
self.path = path
# module this plugin works with
@@ -83,7 +83,7 @@
f = open(os.path.join(self.path , "default-ssl"), "r")
content = f.read()
f.close()
- Shell.command.write_file(os.path.join(Configuration.SITES_AVAILABLE_DIR, "default-ssl"), content)
+ self.core.current_server.command.write_file(os.path.join(Configuration.SITES_AVAILABLE_DIR, "default-ssl"), content)
ssl_vhost = VirtualHost.VirtualHostModel("default-ssl")
#ssl_vhost.toggle(False)
main_window.open_edit_vhost_window("default-ssl")
@@ -114,12 +114,16 @@
self.spinbutton_port = wtree.get_widget("spinbutton_port")
self.entry_ssl_key_location = wtree.get_widget("entry_ssl_key_location")
self.filechooserbutton_ssl_key = wtree.get_widget("filechooserbutton_ssl_key")
+ self.entry_chain = wtree.get_widget("entry_chain")
+ self.filechooserbutton_chain = wtree.get_widget("filechooserbutton_chain")
+
signals = {
"on_button_csr_clicked" : self.on_button_csr_clicked,
"on_treeview_requests_row_activated" : self.on_treeview_requests_row_activated,
"on_button_import_clicked" : self.on_button_import_clicked,
"on_button_import_key_clicked" : self.on_button_import_key_clicked,
- "on_button_key_reset_clicked" : self.on_button_key_reset_clicked
+ "on_button_key_reset_clicked" : self.on_button_key_reset_clicked,
+ "on_button_import_chain_clicked" : self.on_button_import_chain_clicked
}
wtree.signal_autoconnect(signals)
@@ -167,6 +171,28 @@
return table_ssl, "SSL", pixbuf
+ def on_button_import_chain_clicked(self, widget):
+ path = self.filechooserbutton_chain.get_filename()
+
+ if path:
+ f = open(path, "r")
+ text = f.read()
+ f.close()
+
+ timestamp = time.strftime("%y-%m-%d %H:%M:%S", time.localtime() )
+
+ key_path = os.path.join("/etc/apache2/private/", os.path.basename(path) + ' ' + timestamp +'.ca-bundle' )
+
+ if not self.core.current_server.command.sudo_exists(key_path):
+ self.core.current_server.command.write_file(key_path, text)
+ self.entry_chain.set_text(key_path)
+ else:
+ md = gtk.MessageDialog(None, flags=0, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_CLOSE, message_format="A key with that filename already exists")
+ result = md.run()
+ md.destroy()
+
+
+
def on_button_import_key_clicked(self, widget):
path = self.filechooserbutton_ssl_key.get_filename()
@@ -185,8 +211,8 @@
key_path = os.path.join("/etc/ssl/private/", os.path.basename(path))
- if not Shell.command.sudo_exists(key_path):
- Shell.command.write_file(key_path, text)
+ if not self.core.current_server.command.sudo_exists(key_path):
+ self.core.current_server.command.write_file(key_path, text)
self.entry_ssl_key_location.set_text(key_path)
else:
@@ -219,7 +245,7 @@
cert_path = os.path.join("/etc/apache2/ssl/", cert.get_subject().commonName + ' ' + timestamp +'.crt')
- Shell.command.write_file(cert_path, text)
+ self.core.current_server.command.write_file(cert_path, text)
md = gtk.MessageDialog(None, flags=0, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_YES_NO, message_format="Are you sure you want to change the active SSL certificate?")
result = md.run()
@@ -244,9 +270,9 @@
def on_treeview_checked_changed(self, path):
if path and path.endswith(".csr"):
- tdw = TextDisplayWindow(self.path)
+ tdw = TextDisplayWindow(self.core, self.path)
- cert = crypto.load_certificate_request(crypto.FILETYPE_PEM, Shell.command.read_file(path))
+ cert = crypto.load_certificate_request(crypto.FILETYPE_PEM, self.core.current_server.command.read_file(path))
help_array = []
@@ -274,9 +300,9 @@
elif not path or path.endswith(".crt"):
result = gtk.RESPONSE_OK
if path:
- tdw = TextDisplayWindow(self.path)
+ tdw = TextDisplayWindow(self.core, self.path)
- cert = crypto.load_certificate(crypto.FILETYPE_PEM, Shell.command.read_file(path))
+ cert = crypto.load_certificate(crypto.FILETYPE_PEM, self.core.current_server.command.read_file(path))
expired = self.get_expiry_date_hack(cert, path)
start = self.get_start_date_hack(cert, path)
status = "Valid"
@@ -339,12 +365,11 @@
def update_treeview(self):
icon_theme = gtk.icon_theme_get_default()
cert_icon = icon_theme.lookup_icon("application-certificate", 24, 0).load_icon()
- cert_icon_self = icon_theme.lookup_icon("application-certificate", 24, 0).load_icon()
self.treeview_requests_store = gtk.ListStore(bool, gtk.gdk.Pixbuf,str, str, str, str)
self.treeview_requests.set_model(self.treeview_requests_store)
- files = Shell.command.listdir("/etc/apache2/ssl/")
+ files = self.core.current_server.command.listdir("/etc/apache2/ssl/")
files.sort()
domains = list(self.vhost.get_server_alias())
@@ -361,7 +386,7 @@
if path.endswith(".crt"):
- cert = crypto.load_certificate(crypto.FILETYPE_PEM, Shell.command.read_file(full_path))
+ cert = crypto.load_certificate(crypto.FILETYPE_PEM, self.core.current_server.command.read_file(full_path))
domain = cert.get_subject().commonName
domain_match = False
# find domains that are relevent
@@ -370,30 +395,24 @@
if d == domain or (domain[0] == "*" and (d.endswith( domain[1:] ) or d == domain[2:])):
domain_match = True
-
if domain_match:
expired = self.get_expiry_date_hack(cert, full_path)
- icon = cert_icon
-
- if domain == cert.get_issuer().commonName:
- icon = cert_icon_self
-
if cert.has_expired() : expired = "<b>Expired " + expired +"</b>"
if full_path == self.active_cert:
- self.treeview_requests_store.append((True, icon, "<b>Certificate</b>", "<b>"+ domain +"</b>" , "<b>" +expired +"</b>", full_path))
+ self.treeview_requests_store.append((True, cert_icon, "<b>Certificate</b>", "<b>"+ domain +"</b>" , "<b>" +expired +"</b>", full_path))
select = self.treeview_requests.get_selection()
select.select_path(len(self.treeview_requests_store) - 1)
self.treeview_requests.scroll_to_cell(len(self.treeview_requests_store) - 1)
else:
- self.treeview_requests_store.append((False, icon, "Certificate", domain , expired, full_path))
+ self.treeview_requests_store.append((False, cert_icon, "Certificate", domain , expired, full_path))
break
def on_button_csr_clicked(self, widget):
- w = CertificateRequestWindow(self.path)
+ w = CertificateRequestWindow(self.core, self.path)
ServerAdmin = ''
if self.vhost.config.ServerAdmin:
ServerAdmin = self.vhost.config.ServerAdmin.value
@@ -427,6 +446,11 @@
else:
self.entry_ssl_key_location.set_text(self.default_key)
+ if vhost.config.SSLCertificateChainFile:
+ self.entry_chain.set_text(vhost.config. SSLCertificateChainFile.value)
+ else:
+ self.entry_chain.set_text("")
+
port = self.vhost.get_port()
if port and not port == 80:
self.spinbutton_port.set_value(port)
@@ -443,6 +467,12 @@
vhost.config.SSLCertificateKeyFile.value = self.entry_ssl_key_location.get_text()
vhost.set_port( self.spinbutton_port.get_value_as_int() )
vhost.config.SSLCertificateFile.value = self.active_cert
+
+ if self.entry_chain.get_text():
+ vhost.config.SSLCertificateChainFile.value = self.entry_chain.get_text()
+ elif vhost.config.SSLCertificateChainFile:
+ del vhost.config.SSLCertificateChainFile
+
else:
if vhost.config.SSLEngine:
del vhost.config.SSLEngine
@@ -451,14 +481,16 @@
del vhost.config.SSLCertificateFile
if vhost.config.SSLCertificateKeyFile:
- del vhost.config.SSLCertificateKeyFile
-
+ del vhost.config.SSLCertificateKeyFile
+
+ if vhost.config.SSLCertificateChainFile:
+ del vhost.config.SSLCertificateChainFile
+
vhost.set_port(80)
-
return True, ""
-def register( path ):
- return AdvancedVhostPlugin( path )
+def register( core, path ):
+ return AdvancedVhostPlugin( core, path )
=== modified file 'plugins/ssl/ssl.glade'
--- plugins/ssl/ssl.glade 2008-09-03 01:03:28 +0000
+++ plugins/ssl/ssl.glade 2010-05-16 23:57:26 +0000
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.5 on Tue Sep 2 16:38:08 2008 -->
+<!--Generated with glade3 3.4.5 on Fri Sep 26 10:29:27 2008 -->
<glade-interface>
<widget class="GtkWindow" id="window1">
<child>
@@ -52,61 +52,202 @@
<placeholder/>
</child>
<child>
- <widget class="GtkHBox" id="hbox13">
- <property name="visible">True</property>
+ <widget class="GtkHBox" id="hbox8">
<child>
- <widget class="GtkImage" id="image6">
+ <widget class="GtkLinkButton" id="linkbutton_active_cert">
<property name="visible">True</property>
- <property name="stock">gtk-dialog-warning</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">None</property>
+ <property name="relief">GTK_RELIEF_NONE</property>
+ <property name="response_id">0</property>
+ <property name="uri">http://glade.gnome.org</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="padding">8</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label13">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>Warning: Remember you can only apply one SSL cert per IP / Port</b></property>
- <property name="use_markup">True</property>
- </widget>
- <packing>
- <property name="padding">8</property>
- <property name="position">1</property>
- </packing>
+ <placeholder/>
</child>
</widget>
<packing>
+ <property name="left_attach">1</property>
<property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
<property name="y_options"></property>
<property name="x_padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkViewport" id="viewport1">
+ <property name="visible">True</property>
+ <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="hbox4">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Available certificates</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHSeparator" id="hseparator1">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <widget class="GtkTreeView" id="treeview_requests">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_clickable">True</property>
+ <signal name="row_activated" handler="on_treeview_requests_row_activated"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_padding">8</property>
<property name="y_padding">8</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label15">
+ <widget class="GtkHBox" id="hbox3">
<property name="visible">True</property>
- <property name="label" translatable="yes">Import Certificate</property>
+ <child>
+ <widget class="GtkFileChooserButton" id="filechooserbutton_ssl_cert">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_import">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_button_import_clicked"/>
+ <child>
+ <widget class="GtkHBox" id="hbox5">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="stock">gtk-jump-to</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label21">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Import</property>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="padding">8</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</widget>
<packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- <property name="x_padding">8</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label20">
- <property name="label" translatable="yes">Current SSL Certificate</property>
- </widget>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- <property name="x_padding">8</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_csr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">Generate SSL Certificate Request</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_button_csr_clicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="y_options"></property>
+ <property name="x_padding">8</property>
+ <property name="y_padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">If you do not have a certificate you will need to generate a certificate request.</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="y_options"></property>
+ <property name="x_padding">8</property>
+ <property name="y_padding">8</property>
</packing>
</child>
<child>
@@ -116,43 +257,163 @@
<child>
<widget class="GtkTable" id="table2">
<property name="visible">True</property>
- <property name="n_rows">3</property>
+ <property name="n_rows">5</property>
<property name="n_columns">2</property>
<child>
- <widget class="GtkHBox" id="hbox16">
- <property name="visible">True</property>
- <child>
- <widget class="GtkSpinButton" id="spinbutton_port">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="width_chars">6</property>
- <property name="adjustment">0 0 10000 1 10 10</property>
+ <widget class="GtkHBox" id="hbox17">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkFileChooserButton" id="filechooserbutton_chain">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_import_chain">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_button_import_chain_clicked"/>
+ <child>
+ <widget class="GtkHBox" id="hbox18">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImage" id="image8">
+ <property name="visible">True</property>
+ <property name="stock">gtk-jump-to</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label25">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Import</property>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="padding">8</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="y_options"></property>
+ <property name="x_padding">8</property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label24">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Import Chain File</property>
+ </widget>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_chain">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ <property name="x_padding">8</property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label23">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Chain File</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">SSL Key</property>
+ <property name="justify">GTK_JUSTIFY_RIGHT</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ <property name="x_padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox11">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkEntry" id="entry_ssl_key_location">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_key_reset">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_button_key_reset_clicked"/>
+ <child>
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-clear</property>
+ </widget>
+ </child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">8</property>
+ <property name="position">1</property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label16">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Import SSL Key</property>
- </widget>
- <packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ <property name="x_padding">8</property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Port (<i>443</i>)</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
<property name="x_options"></property>
<property name="y_options"></property>
<property name="x_padding">8</property>
@@ -205,18 +466,17 @@
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
<property name="y_options"></property>
<property name="x_padding">8</property>
- <property name="y_padding">8</property>
+ <property name="y_padding">4</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label1">
+ <widget class="GtkLabel" id="label16">
<property name="visible">True</property>
- <property name="label" translatable="yes">Port (<i>443</i>)</property>
- <property name="use_markup">True</property>
+ <property name="label" translatable="yes">Import SSL Key</property>
</widget>
<packing>
<property name="top_attach">2</property>
@@ -227,53 +487,29 @@
</packing>
</child>
<child>
- <widget class="GtkHBox" id="hbox11">
+ <widget class="GtkHBox" id="hbox16">
<property name="visible">True</property>
<child>
- <widget class="GtkEntry" id="entry_ssl_key_location">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </widget>
- </child>
- <child>
- <widget class="GtkButton" id="button_key_reset">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="response_id">0</property>
- <signal name="clicked" handler="on_button_key_reset_clicked"/>
- <child>
- <widget class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="stock">gtk-clear</property>
- </widget>
- </child>
+ <widget class="GtkSpinButton" id="spinbutton_port">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="width_chars">6</property>
+ <property name="adjustment">0 0 10000 1 10 10</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">8</property>
- <property name="position">1</property>
</packing>
</child>
+ <child>
+ <placeholder/>
+ </child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- <property name="x_padding">8</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label14">
- <property name="visible">True</property>
- <property name="label" translatable="yes">SSL Key</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- </widget>
- <packing>
- <property name="x_options"></property>
- <property name="y_options"></property>
- <property name="x_padding">8</property>
+ <property name="y_padding">4</property>
</packing>
</child>
</widget>
@@ -296,202 +532,61 @@
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="label" translatable="yes">If you do not have a certificate you will need to generate a certificate request.</property>
- <property name="wrap">True</property>
- </widget>
- <packing>
- <property name="right_attach">2</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="y_options"></property>
- <property name="x_padding">8</property>
- <property name="y_padding">8</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <child>
- <widget class="GtkLabel" id="label4">
- <property name="visible">True</property>
- </widget>
- </child>
- <child>
- <widget class="GtkButton" id="button_csr">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="label" translatable="yes">Generate SSL Certificate Request</property>
- <property name="response_id">0</property>
- <signal name="clicked" handler="on_button_csr_clicked"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="right_attach">2</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="y_options"></property>
- <property name="x_padding">8</property>
- <property name="y_padding">8</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox3">
- <property name="visible">True</property>
- <child>
- <widget class="GtkFileChooserButton" id="filechooserbutton_ssl_cert">
- <property name="visible">True</property>
- </widget>
- </child>
- <child>
- <widget class="GtkButton" id="button_import">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="response_id">0</property>
- <signal name="clicked" handler="on_button_import_clicked"/>
- <child>
- <widget class="GtkHBox" id="hbox5">
- <property name="visible">True</property>
- <child>
- <widget class="GtkImage" id="image3">
- <property name="visible">True</property>
- <property name="stock">gtk-jump-to</property>
- </widget>
- </child>
- <child>
- <widget class="GtkLabel" id="label21">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Import</property>
- </widget>
- <packing>
- <property name="padding">2</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="padding">8</property>
- <property name="position">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
+ <widget class="GtkLabel" id="label20">
+ <property name="label" translatable="yes">Current SSL Certificate</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ <property name="x_padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Import Certificate</property>
+ </widget>
+ <packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
+ <property name="x_options"></property>
<property name="y_options"></property>
+ <property name="x_padding">8</property>
</packing>
</child>
<child>
- <widget class="GtkViewport" id="viewport1">
+ <widget class="GtkHBox" id="hbox13">
<property name="visible">True</property>
- <property name="resize_mode">GTK_RESIZE_QUEUE</property>
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <child>
- <widget class="GtkHBox" id="hbox4">
- <property name="visible">True</property>
- <child>
- <widget class="GtkLabel" id="label11">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Available certificates</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="padding">8</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="padding">8</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHSeparator" id="hseparator1">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <child>
- <widget class="GtkTreeView" id="treeview_requests">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_clickable">True</property>
- <signal name="row_activated" handler="on_treeview_requests_row_activated"/>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_padding">8</property>
- <property name="y_padding">8</property>
- </packing>
- </child>
- <child>
- <widget class="GtkHBox" id="hbox8">
- <child>
- <widget class="GtkLinkButton" id="linkbutton_active_cert">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="label" translatable="yes">None</property>
- <property name="relief">GTK_RELIEF_NONE</property>
- <property name="response_id">0</property>
- <property name="uri">http://glade.gnome.org</property>
+ <child>
+ <widget class="GtkImage" id="image6">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-warning</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
+ <property name="padding">8</property>
</packing>
</child>
<child>
- <placeholder/>
+ <widget class="GtkLabel" id="label13">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><b>Warning: Remember you can only apply one SSL cert per IP / Port</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="padding">8</property>
+ <property name="position">1</property>
+ </packing>
</child>
</widget>
<packing>
- <property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
<property name="y_options"></property>
<property name="x_padding">8</property>
+ <property name="y_padding">8</property>
</packing>
</child>
</widget>
@@ -521,153 +616,6 @@
<property name="n_rows">7</property>
<property name="n_columns">2</property>
<child>
- <widget class="GtkComboBox" id="combobox_country">
- <property name="visible">True</property>
- <property name="items" translatable="yes"></property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- <property name="y_padding">4</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label5">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Domain</property>
- </widget>
- <packing>
- <property name="x_options"></property>
- </packing>
- </child>
- <child>
- <widget class="GtkComboBox" id="combobox_domain">
- <property name="visible">True</property>
- <property name="items" translatable="yes"></property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options"></property>
- <property name="y_padding">4</property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label6">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Country</property>
- </widget>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options"></property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label7">
- <property name="visible">True</property>
- <property name="label" translatable="yes">State or province name</property>
- </widget>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options"></property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label8">
- <property name="visible">True</property>
- <property name="label" translatable="yes">City / locality name</property>
- </widget>
- <packing>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options"></property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label9">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Organization name</property>
- </widget>
- <packing>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="x_options"></property>
- </packing>
- </child>
- <child>
- <widget class="GtkLabel" id="label10">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Organizational unit name</property>
- </widget>
- <packing>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_options"></property>
- <property name="x_padding">8</property>
- </packing>
- </child>
- <child>
- <widget class="GtkEntry" id="entry_state">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="tooltip_text">The state or province where your organization is legally located. Can not be abbreviated. </property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_padding">4</property>
- </packing>
- </child>
- <child>
- <widget class="GtkEntry" id="entry_city">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="tooltip_text">The city where your organization is legally located. </property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="y_padding">4</property>
- </packing>
- </child>
- <child>
- <widget class="GtkEntry" id="entry_organisation">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="tooltip_text">The exact legal name of your organization. Do not abbreviate your organization name. </property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="y_padding">4</property>
- </packing>
- </child>
- <child>
- <widget class="GtkEntry" id="entry_organisation_unit">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="tooltip_text">Section of the organization </property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="y_padding">4</property>
- </packing>
- </child>
- <child>
<widget class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -754,6 +702,153 @@
<property name="y_padding">8</property>
</packing>
</child>
+ <child>
+ <widget class="GtkEntry" id="entry_organisation_unit">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text">Section of the organization </property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_organisation">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text">The exact legal name of your organization. Do not abbreviate your organization name. </property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_city">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text">The city where your organization is legally located. </property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_state">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text">The state or province where your organization is legally located. Can not be abbreviated. </property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Organizational unit name</property>
+ </widget>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options"></property>
+ <property name="x_padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Organization name</property>
+ </widget>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">City / locality name</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">State or province name</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Country</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="combobox_domain">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes"></property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Domain</property>
+ </widget>
+ <packing>
+ <property name="x_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="combobox_country">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes"></property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="expand">False</property>
=== modified file 'plugins/ssl/text_display.py'
--- plugins/ssl/text_display.py 2008-09-03 01:03:28 +0000
+++ plugins/ssl/text_display.py 2010-05-16 23:57:26 +0000
@@ -29,13 +29,13 @@
sys.exit(1)
import os
-from RapacheCore import Shell
class TextDisplayWindow:
- def __init__(self, path):
-
-
+ def __init__(self, core, path):
+
+ self.core = core
+
# The path to the plugin
self.glade_path = path
@@ -119,7 +119,7 @@
self.label_help.set_markup(help_text)
self.label_path.set_text("File : " + path )
- content = Shell.command.read_file( path)
+ content = self.core.current_server.command.read_file( path)
self.textview_content.get_buffer().set_text( content )
if apply_button:
=== modified file 'rapache'
--- rapache 2008-07-25 00:07:25 +0000
+++ rapache 2010-05-16 23:57:26 +0000
@@ -35,18 +35,20 @@
from RapacheGtk.RapacheGui import MainWindow
from RapacheGtk.WarningWindow import WarningWindow
from RapacheCore import Configuration
-
+from RapacheCore.Core import RapacheCore
if __name__ == "__main__":
- current_path = os.path.abspath(os.path.dirname(__file__))
- if ( os.path.exists( current_path+"/RapacheCore" ) ):
- #self-contained mode
- Configuration.APPPATH = os.path.abspath(os.path.dirname(__file__))
- Configuration.GLADEPATH = Configuration.APPPATH + "/Glade"
-
- if( os.path.isdir( Configuration.SITES_AVAILABLE_DIR ) and os.path.isdir( Configuration.SITES_ENABLED_DIR )):
- hwg = MainWindow()
- gtk.main()
- else:
- ww = WarningWindow("Apache isn't installed. Rapache has nothing to manage.")
- gtk.main()
+ current_path = os.path.abspath(os.path.dirname(__file__))
+ if ( os.path.exists( current_path+"/RapacheCore" ) ):
+ #self-contained mode
+ Configuration.APPPATH = os.path.abspath(os.path.dirname(__file__))
+ Configuration.GLADEPATH = Configuration.APPPATH + "/Glade"
+
+ # Insure config path exists
+ Configuration.CONFIG_PATH = os.path.expanduser(Configuration.CONFIG_PATH)
+ if not os.path.exists(Configuration.CONFIG_PATH):
+ os.makedirs(Configuration.CONFIG_PATH)
+
+ hwg = MainWindow( RapacheCore() )
+ gtk.main()
+