Merge lp:~ralsina/ubuntuone-windows-installer/put-in-autostart into lp:ubuntuone-windows-installer

Proposed by Roberto Alsina
Status: Merged
Approved by: Roberto Alsina
Approved revision: 66
Merged at revision: 59
Proposed branch: lp:~ralsina/ubuntuone-windows-installer/put-in-autostart
Merge into: lp:ubuntuone-windows-installer
Diff against target: 393 lines (+200/-20)
9 files modified
data/qt/congratulations.ui (+44/-9)
ubuntuone_installer/gui/qt/gui.py (+3/-0)
ubuntuone_installer/gui/qt/setup_account.py (+11/-7)
ubuntuone_installer/gui/qt/tests/test_gui.py (+12/-1)
ubuntuone_installer/gui/qt/tests/test_setup_account.py (+10/-1)
ubuntuone_installer/gui/qt/utils/__init__.py (+2/-0)
ubuntuone_installer/gui/qt/utils/linux.py (+8/-0)
ubuntuone_installer/gui/qt/utils/tests/test_windows.py (+83/-0)
ubuntuone_installer/gui/qt/utils/windows.py (+27/-2)
To merge this branch: bzr merge lp:~ralsina/ubuntuone-windows-installer/put-in-autostart
Reviewer Review Type Date Requested Status
Natalia Bidart (community) Approve
Review via email: mp+73670@code.launchpad.net

Commit message

* Adds a missing image to the final page of the wizard
* Adds syncdaemon to autostart

Description of the change

* Adds a missing image to the final page of the wizard
* Adds syncdaemon to autostart

To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

ubuntuone_installer/gui/qt/utils/tests/test_windows.py:
    96: [C0301] Line too long (89/79)
    97: [C0301] Line too long (148/79)
    73: [C0103, FakeRegistry.ConnectRegistry] Invalid name "ConnectRegistry" (should match ([a-z_][a-z0-9_]{2,79}$|setUp|tearDown))
    73: [C0111, FakeRegistry.ConnectRegistry] Missing docstring
    77: [C0103, FakeRegistry.OpenKey] Invalid name "OpenKey" (should match ([a-z_][a-z0-9_]{2,79}$|setUp|tearDown))
    77: [C0111, FakeRegistry.OpenKey] Missing docstring
    81: [C0103, FakeRegistry.CloseKey] Invalid name "CloseKey" (should match ([a-z_][a-z0-9_]{2,79}$|setUp|tearDown))
    81: [C0111, FakeRegistry.CloseKey] Missing docstring
    84: [C0103, FakeRegistry.QueryValueEx] Invalid name "QueryValueEx" (should match ([a-z_][a-z0-9_]{2,79}$|setUp|tearDown))
    84: [C0111, FakeRegistry.QueryValueEx] Missing docstring
    85: [W0201, FakeRegistry.QueryValueEx] Attribute 'query_args' defined outside __init__
    78: [W0201, FakeRegistry.OpenKey] Attribute 'openkey_args' defined outside __init__
    82: [W0201, FakeRegistry.CloseKey] Attribute 'closekey_args' defined outside __init__
    74: [W0201, FakeRegistry.ConnectRegistry] Attribute 'connect_args' defined outside __init__
    27: [W0611] Unused import _winreg

ubuntuone_installer/gui/qt/utils/windows.py:
    74: [C0301] Line too long (112/79)
    78: [E0602, add_syncdaemon_to_autostart] Undefined variable 'WindowsError'

review: Needs Fixing
Revision history for this message
Roberto Alsina (ralsina) wrote :

Most of those were a missing push, the last one only appears on Linux, so added a disable for it.

Revision history for this message
Leo Arias (elopio) wrote :

Why did you kept the empty label?

+ <string/>

Revision history for this message
Roberto Alsina (ralsina) wrote :

> Why did you kept the empty label?
>
> + <string/>

There is probably going to be another branch to add an image there after design sees how this looks, and didn't want to make the diff grow more than what's needed.

Revision history for this message
Leo Arias (elopio) wrote :

Good. I still don't understand the whole registry thing, but you have my full confidence and a symbolic +1. :)

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

The branch looks good, but after testing IRL I'm not sure that syncdaemon was added to the startup. Roberto said he will do some more work on this.

review: Needs Fixing
Revision history for this message
Roberto Alsina (ralsina) wrote :

The tests IRL don't work unless ubuntuone-windows-installer is a .exe file. You can test it with tonight's build that includes this branch.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Tested IRL with the beta2 bundle and works fine.

review: Approve
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Oh, I just realized tests are broken:

Traceback (most recent call last):
  File "/home/nessita/canonical/u1/windows-installer/review_put-in-autostart/ubuntuone_installer/gui/qt/tests/test_gui.py", line 153, in setUp
    self.patch(gui.utils, "add_syncdaemon_to_autostart", NO_OP)
exceptions.AttributeError: 'module' object has no attribute 'utils'

review: Needs Fixing
61. By Roberto Alsina

fix tests

62. By Roberto Alsina

pep8

63. By Roberto Alsina

cleaner fix for set_up_button noise.

64. By Roberto Alsina

added missing super call

65. By Roberto Alsina

ARGH

66. By Roberto Alsina

push

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'data/qt/congratulations.ui'
--- data/qt/congratulations.ui 2011-09-02 12:58:29 +0000
+++ data/qt/congratulations.ui 2011-09-12 19:52:24 +0000
@@ -6,8 +6,8 @@
6 <rect>6 <rect>
7 <x>0</x>7 <x>0</x>
8 <y>0</y>8 <y>0</y>
9 <width>521</width>9 <width>622</width>
10 <height>387</height>10 <height>331</height>
11 </rect>11 </rect>
12 </property>12 </property>
13 <property name="windowTitle">13 <property name="windowTitle">
@@ -35,11 +35,44 @@
35 </widget>35 </widget>
36 </item>36 </item>
37 <item>37 <item>
38 <widget class="QLabel" name="label_2">38 <layout class="QHBoxLayout" name="horizontalLayout_2">
39 <property name="text">39 <item>
40 <string>Nice picture goes here</string>40 <spacer name="horizontalSpacer">
41 </property>41 <property name="orientation">
42 </widget>42 <enum>Qt::Horizontal</enum>
43 </property>
44 <property name="sizeHint" stdset="0">
45 <size>
46 <width>40</width>
47 <height>20</height>
48 </size>
49 </property>
50 </spacer>
51 </item>
52 <item>
53 <widget class="QLabel" name="label_2">
54 <property name="text">
55 <string/>
56 </property>
57 <property name="pixmap">
58 <pixmap resource="images.qrc">:/win_installer_graphic.png</pixmap>
59 </property>
60 </widget>
61 </item>
62 <item>
63 <spacer name="horizontalSpacer_2">
64 <property name="orientation">
65 <enum>Qt::Horizontal</enum>
66 </property>
67 <property name="sizeHint" stdset="0">
68 <size>
69 <width>40</width>
70 <height>20</height>
71 </size>
72 </property>
73 </spacer>
74 </item>
75 </layout>
43 </item>76 </item>
44 <item>77 <item>
45 <widget class="QLabel" name="label_3">78 <widget class="QLabel" name="label_3">
@@ -60,7 +93,7 @@
60 <item>93 <item>
61 <widget class="QLabel" name="label_4">94 <widget class="QLabel" name="label_4">
62 <property name="text">95 <property name="text">
63 <string>IMAGE GOES HERE?</string>96 <string/>
64 </property>97 </property>
65 </widget>98 </widget>
66 </item>99 </item>
@@ -109,6 +142,8 @@
109 </item>142 </item>
110 </layout>143 </layout>
111 </widget>144 </widget>
112 <resources/>145 <resources>
146 <include location="images.qrc"/>
147 </resources>
113 <connections/>148 <connections/>
114</ui>149</ui>
115150
=== modified file 'ubuntuone_installer/gui/qt/gui.py'
--- ubuntuone_installer/gui/qt/gui.py 2011-09-08 14:18:30 +0000
+++ ubuntuone_installer/gui/qt/gui.py 2011-09-12 19:52:24 +0000
@@ -243,6 +243,9 @@
243 self.wizard().button(QtGui.QWizard.FinishButton).style().polish(243 self.wizard().button(QtGui.QWizard.FinishButton).style().polish(
244 self.wizard().button(QtGui.QWizard.FinishButton))244 self.wizard().button(QtGui.QWizard.FinishButton))
245245
246 # Add syncdaemon to autostart
247 qt.utils.add_syncdaemon_to_autostart()
248
246249
247class MainWindow(QtGui.QWizard):250class MainWindow(QtGui.QWizard):
248251
249252
=== modified file 'ubuntuone_installer/gui/qt/setup_account.py'
--- ubuntuone_installer/gui/qt/setup_account.py 2011-09-08 13:41:10 +0000
+++ ubuntuone_installer/gui/qt/setup_account.py 2011-09-12 19:52:24 +0000
@@ -178,25 +178,29 @@
178 """Set set_up_button as default button when the page is shown."""178 """Set set_up_button as default button when the page is shown."""
179 # This method should stays here because if we move it to initializePage179 # This method should stays here because if we move it to initializePage
180 # set_up_button won't take the proper style for hover and press180 # set_up_button won't take the proper style for hover and press
181 self.set_up_button.setVisible(True)181 if self.set_up_button is not None:
182 self.set_up_button.setDefault(True)182 self.set_up_button.setVisible(True)
183 if not self.set_up_button.isEnabled():183 self.set_up_button.setDefault(True)
184 self.set_up_button.setProperty("DisabledState", True)184 if not self.set_up_button.isEnabled():
185 self.set_up_button.style().unpolish(self.set_up_button)185 self.set_up_button.setProperty("DisabledState", True)
186 self.set_up_button.style().polish(self.set_up_button)186 self.set_up_button.style().unpolish(self.set_up_button)
187 self.set_up_button.style().polish(self.set_up_button)
187 self.connect(QtGui.QApplication.instance(),188 self.connect(QtGui.QApplication.instance(),
188 QtCore.SIGNAL("focusChanged(QWidget*, QWidget*)"),189 QtCore.SIGNAL("focusChanged(QWidget*, QWidget*)"),
189 self.focus_changed)190 self.focus_changed)
191 super(SetupAccountPage, self).showEvent(event)
190192
191 def hideEvent(self, event):193 def hideEvent(self, event):
192 """Disconnect the focusChanged signal when the page change."""194 """Disconnect the focusChanged signal when the page change."""
193 self.set_up_button.setVisible(False)195 if self.set_up_button is not None:
196 self.set_up_button.setVisible(False)
194 try:197 try:
195 self.disconnect(QtGui.QApplication.instance(),198 self.disconnect(QtGui.QApplication.instance(),
196 QtCore.SIGNAL("focusChanged(QWidget*, QWidget*)"),199 QtCore.SIGNAL("focusChanged(QWidget*, QWidget*)"),
197 self.focus_changed)200 self.focus_changed)
198 except TypeError:201 except TypeError:
199 pass202 pass
203 super(SetupAccountPage, self).hideEvent(event)
200204
201205
202def is_min_required_password(password):206def is_min_required_password(password):
203207
=== modified file 'ubuntuone_installer/gui/qt/tests/test_gui.py'
--- ubuntuone_installer/gui/qt/tests/test_gui.py 2011-09-12 18:18:54 +0000
+++ ubuntuone_installer/gui/qt/tests/test_gui.py 2011-09-12 19:52:24 +0000
@@ -30,7 +30,7 @@
3030
31from ubuntuone_installer.gui import NEXT31from ubuntuone_installer.gui import NEXT
32from ubuntuone_installer.gui.qt import gui, forgotten, utils32from ubuntuone_installer.gui.qt import gui, forgotten, utils
33from ubuntuone_installer.gui.qt.tests import BaseTestCase33from ubuntuone_installer.gui.qt.tests import BaseTestCase, NO_OP
3434
3535
36class FakeController(object):36class FakeController(object):
@@ -150,6 +150,7 @@
150 self.patch(gui, "LocalFoldersPage", FakeLocalFoldersPage)150 self.patch(gui, "LocalFoldersPage", FakeLocalFoldersPage)
151 self.patch(qt.preferences, "PreferencesPanel", FakePreferencesPanel)151 self.patch(qt.preferences, "PreferencesPanel", FakePreferencesPanel)
152 self.patch(qt.folders, "FoldersPanel", FakeFoldersPanel)152 self.patch(qt.folders, "FoldersPanel", FakeFoldersPanel)
153 self.patch(gui.qt.utils, "add_syncdaemon_to_autostart", NO_OP)
153 super(MainWindowTestCase, self).setUp()154 super(MainWindowTestCase, self).setUp()
154 setup_page = self.ui.page(self.ui.setup_account_page_id)155 setup_page = self.ui.page(self.ui.setup_account_page_id)
155 setup_page.initializePage()156 setup_page.initializePage()
@@ -561,6 +562,16 @@
561 QtCore.QCoreApplication.instance().processEvents()562 QtCore.QCoreApplication.instance().processEvents()
562 self.assertEqual(self.ui.result(), self.ui.Rejected)563 self.assertEqual(self.ui.result(), self.ui.Rejected)
563564
565 def test_congratulations_adds_to_autostart(self):
566 """Test that syncdaemon is now on autostart."""
567 self.patch(gui.qt.utils, "add_syncdaemon_to_autostart",
568 self._set_called)
569 # Show the Congratulations page
570 self.ui.setStartId(self.ui.CONGRATULATIONS_PAGE)
571 self.ui.restart()
572 # Check if syncdaemon was added to autostart
573 self.assertEqual(self._called, ((), {}))
574
564575
565class FakeSignal(object):576class FakeSignal(object):
566577
567578
=== modified file 'ubuntuone_installer/gui/qt/tests/test_setup_account.py'
--- ubuntuone_installer/gui/qt/tests/test_setup_account.py 2011-09-07 14:15:39 +0000
+++ ubuntuone_installer/gui/qt/tests/test_setup_account.py 2011-09-12 19:52:24 +0000
@@ -229,7 +229,6 @@
229 # so we don't rely on any SSO behaviour229 # so we don't rely on any SSO behaviour
230 super(SetupAccountFakeWizardTestCase, self).setUp()230 super(SetupAccountFakeWizardTestCase, self).setUp()
231 self.patch(self.ui, 'wizard', FakeWizard)231 self.patch(self.ui, 'wizard', FakeWizard)
232 self.patch(self.ui, "set_up_button", QtGui.QPushButton())
233232
234 def test_blank_name(self):233 def test_blank_name(self):
235 """Status when the name field is blank (spaces).234 """Status when the name field is blank (spaces).
@@ -322,3 +321,13 @@
322 self.addCleanup(self.ui.hide)321 self.addCleanup(self.ui.hide)
323 self.ui.focus_changed(None, self.ui.ui.password_edit)322 self.ui.focus_changed(None, self.ui.ui.password_edit)
324 self.assertTrue(self.ui.ui.password_assistance.isVisible())323 self.assertTrue(self.ui.ui.password_assistance.isVisible())
324
325 def test_hide_event(self):
326 """Check that hide_event works when set_up_button is none."""
327 self.assertEqual(self.ui.set_up_button, None)
328 self.ui.hideEvent(QtGui.QHideEvent())
329
330 def test_show_event(self):
331 """Check that show_event works when set_up_button is none."""
332 self.assertEqual(self.ui.set_up_button, None)
333 self.ui.showEvent(QtGui.QShowEvent())
325334
=== modified file 'ubuntuone_installer/gui/qt/utils/__init__.py'
--- ubuntuone_installer/gui/qt/utils/__init__.py 2011-08-30 14:11:48 +0000
+++ ubuntuone_installer/gui/qt/utils/__init__.py 2011-09-12 19:52:24 +0000
@@ -26,9 +26,11 @@
26 from ubuntuone_installer.gui.qt.utils import windows26 from ubuntuone_installer.gui.qt.utils import windows
27 uninstall_application = windows.uninstall_application27 uninstall_application = windows.uninstall_application
28 start_control_panel = windows.start_control_panel28 start_control_panel = windows.start_control_panel
29 add_syncdaemon_to_autostart = windows.add_syncdaemon_to_autostart
29 default_folders = windows.default_folders30 default_folders = windows.default_folders
30else:31else:
31 from ubuntuone_installer.gui.qt.utils import linux32 from ubuntuone_installer.gui.qt.utils import linux
32 uninstall_application = linux.uninstall_application33 uninstall_application = linux.uninstall_application
33 start_control_panel = linux.start_control_panel34 start_control_panel = linux.start_control_panel
35 add_syncdaemon_to_autostart = linux.add_syncdaemon_to_autostart
34 default_folders = linux.default_folders36 default_folders = linux.default_folders
3537
=== modified file 'ubuntuone_installer/gui/qt/utils/linux.py'
--- ubuntuone_installer/gui/qt/utils/linux.py 2011-09-01 11:15:49 +0000
+++ ubuntuone_installer/gui/qt/utils/linux.py 2011-09-12 19:52:24 +0000
@@ -32,6 +32,14 @@
32 subprocess.Popen(["ubuntuone-control-panel-qt", ])32 subprocess.Popen(["ubuntuone-control-panel-qt", ])
3333
3434
35def remove_syncdaemon_from_autostart():
36 """Remove syncdaemon from the session's autostart."""
37
38
39def add_syncdaemon_to_autostart():
40 """Add syncdaemon to the session's autostart."""
41
42
35def default_folders():43def default_folders():
36 """Return a list of the folders to add by default."""44 """Return a list of the folders to add by default."""
37 # FIXME: this should be taken from ~/.config/user-dirs.dirs45 # FIXME: this should be taken from ~/.config/user-dirs.dirs
3846
=== modified file 'ubuntuone_installer/gui/qt/utils/tests/test_windows.py'
--- ubuntuone_installer/gui/qt/utils/tests/test_windows.py 2011-09-01 18:25:44 +0000
+++ ubuntuone_installer/gui/qt/utils/tests/test_windows.py 2011-09-12 19:52:24 +0000
@@ -86,6 +86,89 @@
86 self.assertTrue(0 == self._called[0][5])86 self.assertTrue(0 == self._called[0][5])
8787
8888
89class FakeRegistry(object):
90 """A fake registry."""
91 # pylint: disable=C0103
92 HKEY_CURRENT_USER = 2
93 KEY_ALL_ACCESS = 4
94 REG_SZ = 1
95
96 def __init__(self):
97 self.HKEY_CURRENT_USER = 2
98 self.KEY_ALL_ACCESS = 4
99 self.connect_args = None
100 self.openkey_args = None
101 self.closekey_args = None
102 self.query_args = None
103 self.set_args = []
104
105 def ConnectRegistry(self, *args, **kwargs):
106 """Fake ConnectRegistry."""
107 self.connect_args = (args, kwargs)
108 return "REGISTRY"
109
110 def OpenKey(self, *args, **kwargs):
111 """Fake OpenKey."""
112 self.openkey_args = (args, kwargs)
113 return "KEY"
114
115 def CloseKey(self, *args, **kwargs):
116 """Fake CloseKey."""
117 self.closekey_args = (args, kwargs)
118
119 def QueryValueEx(self, *args, **kwargs):
120 """Fake QueryValueEx."""
121 self.query_args = (args, kwargs)
122
123 def SetValueEx(self, *args, **kwargs):
124 """Fake SetValueEx."""
125 self.set_args.append((args, kwargs))
126
127
128class AutostartTestCase(BaseTestCase):
129 """Test add_syncdaemon_to_autostart."""
130
131 def setUp(self):
132 """Initialize this test instance."""
133 self.registry = FakeRegistry()
134 self.patch(utils.windows, "_winreg", self.registry)
135 super(AutostartTestCase, self).setUp()
136
137 def test_add_syncdaemon_to_autostart(self):
138 """Check that the registry is updated correctly."""
139 # I can't patch sys because frozen is not there by default
140 sys.frozen = True
141
142 def clean_frozen():
143 """Remove sys.frozen."""
144 del sys.frozen
145
146 self.addCleanup(clean_frozen)
147 utils.windows.add_syncdaemon_to_autostart()
148 self.assertEqual(self.registry.connect_args,
149 ((None, self.registry.HKEY_CURRENT_USER), {}))
150 self.assertEqual(self.registry.openkey_args,
151 (('REGISTRY', utils.windows.AUTORUN_KEY, 0,
152 self.registry.KEY_ALL_ACCESS), {}))
153 self.assertEqual(self.registry.closekey_args, (('KEY',), {}))
154 self.assertEqual(self.registry.query_args, None)
155 self.assertEqual(self.registry.set_args,
156 [(('KEY', 'Ubuntu One', 0, 1,
157 'C:\\Python27\\ubuntuone-syncdaemon.exe'), {}),
158 (('KEY', 'Ubuntu One Icon', 0, 1,
159 'C:\\Python27\\ubuntuone-control-panel-qt.exe --minimized'),
160 {})])
161
162 def test_not_added_if_not_frozen(self):
163 """Not frozen binaries are not added to the registry."""
164 utils.windows.add_syncdaemon_to_autostart()
165 self.assertEqual(self.registry.connect_args, None)
166 self.assertEqual(self.registry.openkey_args, None)
167 self.assertEqual(self.registry.closekey_args, None)
168 self.assertEqual(self.registry.query_args, None)
169 self.assertEqual(self.registry.set_args, [])
170
171
89class DefaultFoldersTestCase(BaseTestCase):172class DefaultFoldersTestCase(BaseTestCase):
90173
91 """Test the default suggested UDFs."""174 """Test the default suggested UDFs."""
92175
=== modified file 'ubuntuone_installer/gui/qt/utils/windows.py'
--- ubuntuone_installer/gui/qt/utils/windows.py 2011-09-01 10:32:51 +0000
+++ ubuntuone_installer/gui/qt/utils/windows.py 2011-09-12 19:52:24 +0000
@@ -19,6 +19,7 @@
19"""Utils Functions Windows specific."""19"""Utils Functions Windows specific."""
2020
2121
22import ctypes
22import os23import os
23import subprocess24import subprocess
24import sys25import sys
@@ -26,8 +27,10 @@
26# Avoid pylint error on Linux27# Avoid pylint error on Linux
27# pylint: disable=F040128# pylint: disable=F0401
28import win32api29import win32api
30import _winreg
29# pylint: enable=F040131# pylint: enable=F0401
30import ctypes32
33AUTORUN_KEY = r"Software\Microsoft\Windows\CurrentVersion\Run"
3134
3235
33def uninstall_application():36def uninstall_application():
@@ -48,7 +51,7 @@
48 """Start the control panel."""51 """Start the control panel."""
49 # If we are in windows and "frozen", assume it's in52 # If we are in windows and "frozen", assume it's in
50 # the same folder as this .exe53 # the same folder as this .exe
51 if sys.platform == "win32" and hasattr(sys, "frozen"):54 if hasattr(sys, "frozen"):
52 cp_path = os.path.join(os.path.dirname(55 cp_path = os.path.join(os.path.dirname(
53 os.path.abspath(sys.executable)),56 os.path.abspath(sys.executable)),
54 "ubuntuone-control-panel-qt.exe")57 "ubuntuone-control-panel-qt.exe")
@@ -57,6 +60,28 @@
57 subprocess.Popen([cp_path, ])60 subprocess.Popen([cp_path, ])
5861
5962
63def add_syncdaemon_to_autostart():
64 """Add syncdaemon to the session's autostart."""
65 if hasattr(sys, "frozen"):
66 sd_path = os.path.join(os.path.dirname(
67 os.path.abspath(sys.executable)),
68 "ubuntuone-syncdaemon.exe")
69 u1cp_path = os.path.join(os.path.dirname(
70 os.path.abspath(sys.executable)),
71 "ubuntuone-control-panel-qt.exe")
72 else:
73 return
74 registry = _winreg.ConnectRegistry(None, _winreg.HKEY_CURRENT_USER)
75 key = _winreg.OpenKey(registry,
76 AUTORUN_KEY,
77 0, _winreg.KEY_ALL_ACCESS)
78 # pylint: disable=E0602
79 _winreg.SetValueEx(key, "Ubuntu One", 0, _winreg.REG_SZ, sd_path)
80 _winreg.SetValueEx(key, "Ubuntu One Icon", 0, _winreg.REG_SZ,
81 u1cp_path + " --minimized")
82 _winreg.CloseKey(key)
83
84
60def default_folders():85def default_folders():
61 """Return a list of the folders to add by default."""86 """Return a list of the folders to add by default."""
62 # XXXX to be replaced by calls to xdg_base_directory's87 # XXXX to be replaced by calls to xdg_base_directory's

Subscribers

People subscribed via source and target branches