Index: conduit/datatypes/Video.py
===================================================================
--- conduit/datatypes/Video.py	(revision 1494)
+++ conduit/datatypes/Video.py	(working copy)
@@ -29,6 +29,8 @@
 
     def __init__(self, URI, **kwargs):
         File.File.__init__(self, URI, **kwargs)
+        self._title = None
+        self._description = None
 
     def get_video_duration(self):
         return None
@@ -36,4 +38,22 @@
     def get_video_size(self):
         return None,None
 
+    def get_description(self):
+        """
+        @returns: the video's description
+        """
+        return self._description
 
+    def set_description(self, description):
+        self._description = description
+        
+    def __getstate__(self):
+        data = File.File.__getstate__(self)
+        data["description"] = self._description
+        return data
+
+    def __setstate__(self, data):
+        self.pb = None
+        self._description = data["description"]
+        File.File.__setstate__(self, data)
+
Index: conduit/modules/GoogleModule/GoogleModule.py
===================================================================
--- conduit/modules/GoogleModule/GoogleModule.py	(revision 1494)
+++ conduit/modules/GoogleModule/GoogleModule.py	(working copy)
@@ -33,11 +33,12 @@
     import gdata.calendar.service
     import gdata.contacts.service
     import gdata.docs.service
+    import gdata.youtube.service
 
     MODULES = {
         "GoogleCalendarTwoWay" : { "type": "dataprovider" },
         "PicasaTwoWay" :         { "type": "dataprovider" },
-        "YouTubeSource" :        { "type": "dataprovider" },    
+        "YouTubeTwoWay" :        { "type": "dataprovider" },    
         "ContactsTwoWay" :       { "type": "dataprovider" },
 #        "DocumentsSink" :        { "type": "dataprovider" },
     }
@@ -1231,8 +1232,31 @@
             self._set_password(password.get_text())
         dlg.destroy()   
 
-class YouTubeSource(DataProvider.DataSource):
+class VideoUploadInfo:
     """
+    Upload information container, this way we can add info
+    and keep the _upload_info method on the VideoSink retain
+    its API
+    
+    Default category for videos is People/Blogs (for lack of a better
+    general category).
+    
+    Default name and description are placeholders, or the generated XML is invalid
+    as the corresponding elements automatically self-close.
+    
+    Default keyword is "miscellaneous" as the upload fails if no keywords
+    are specified.
+    """
+    def __init__ (self, url, mimeType, name=None, keywords=None, description=None, category=None):
+        self.url = url
+        self.mimeType = mimeType
+        self.name = name or _("Unknown")
+        self.keywords = keywords or (_("miscellaneous"),)
+        self.description = description or _("No description.")
+        self.category = category or "People" # Note: don't translate this; it's an identifier
+
+class YouTubeTwoWay(_GoogleBase, DataProvider.TwoWay):
+    """
     Downloads YouTube videos using the gdata API.
     Based on youtube client from : Philippe Normand (phil at base-art dot net)
     http://base-art.net/Articles/87/
@@ -1240,7 +1264,8 @@
     _name_ = _("YouTube")
     _description_ = _("Sync data from YouTube")
     _category_ = conduit.dataproviders.CATEGORY_MISC
-    _module_type_ = "source"
+    _module_type_ = "twoway"
+    _in_type_ = "file/video"
     _out_type_ = "file/video"
     _icon_ = "youtube"
 
@@ -1254,49 +1279,44 @@
     UPLOAD_URL="http://uploads.gdata.youtube.com/feeds/api/users/%(username)s/uploads"
 
     def __init__(self, *args):
-        DataProvider.DataSource.__init__(self)
+        youtube_service = gdata.youtube.service.YouTubeService()
+        youtube_service.client_id = self.UPLOAD_CLIENT_ID
+        youtube_service.developer_key = self.UPLOAD_DEVELOPER_KEY
+
+        _GoogleBase.__init__(self,youtube_service)
+        DataProvider.TwoWay.__init__(self)
+
         self.entries = None
-        self.username = ""
         self.max_downloads = 0
-        #filter type {0 = mostviewed, 1 = toprated, 2 = user}
+        #filter type {0 = mostviewed, 1 = toprated, 2 = user upload, 3 = user favorites}
         self.filter_type = 0
-        #filter user type {0 = upload, 1 = favorites}
-        self.user_filter_type = 0
 
-    def initialize(self):
-        return True
-
     def configure(self, window):
         tree = Utils.dataprovider_glade_get_widget (
                 __file__,
                 "youtube-config.glade",
-                "YouTubeSourceConfigDialog") 
+                "YouTubeTwoWayConfigDialog") 
 
-        dlg = tree.get_widget ("YouTubeSourceConfigDialog")
+        dlg = tree.get_widget ("YouTubeTwoWayConfigDialog")
         mostviewedRb = tree.get_widget("mostviewed")
         topratedRb = tree.get_widget("toprated")
-        byuserRb = tree.get_widget("byuser")
-        user_frame = tree.get_widget("frame")
         uploadedbyRb = tree.get_widget("uploadedby")
         favoritesofRb = tree.get_widget("favoritesof")
-        user = tree.get_widget("user")
-        maxdownloads = tree.get_widget("maxdownloads")
+        max_downloads = tree.get_widget("maxdownloads")
+        username = tree.get_widget("username")
+        password = tree.get_widget("password")
 
-        byuserRb.connect("toggled", self._filter_user_toggled_cb, user_frame)
-
         if self.filter_type == 0:
             mostviewedRb.set_active(True)
         elif self.filter_type == 1:
             topratedRb.set_active(True)
+        elif self.filter_type == 2:
+            uploadedbyRb.set_active(True)
         else:
-            byuserRb.set_active(True)
-            user_frame.set_sensitive(True)
-            if self.user_filter_type == 0:
-                uploadedbyRb.set_active(True)
-            else:
-                favoritesofRb.set_active(True)
-            user.set_text(self.username)
-        maxdownloads.set_value(self.max_downloads)
+            favoritesofRb.set_active(True)
+        max_downloads.set_value(self.max_downloads)
+        username.set_text(self.username)
+        password.set_text(self.password)
 
         response = Utils.run_dialog(dlg, window)
         if response == True:
@@ -1304,32 +1324,58 @@
                 self.filter_type = 0
             elif topratedRb.get_active():
                 self.filter_type = 1
+            elif uploadedbyRb.get_active():
+                self.filter_type = 2
             else:
-                self.filter_type = 2
-                if uploadedbyRb.get_active():
-                    self.user_filter_type = 0
-                else:
-                    self.user_filter_type = 1
-                self.username = user.get_text()
-            self.max_downloads = int(maxdownloads.get_value())
+                self.filter_type = 3
+            self.max_downloads = int(max_downloads.get_value())
+            self.username = username.get_text()
+            self.password = password.get_text()
 
         dlg.destroy()
 
+    def _get_video_info (self, id):
+        if self.entries.has_key(id):
+            return self.entries[id]
+        else:
+            return None
+
+    def _do_login(self):
+        # The YouTube login URL is slightly different to the normal Google one
+        self.service.ClientLogin(self.username, self.password, auth_service_url="https://www.google.com/youtube/accounts/ClientLogin")
+
+    def _upload_video (self, uploadInfo):
+        try:
+            self.gvideo = gdata.youtube.YouTubeVideoEntry()
+            self.gvideo.media = gdata.media.Group(
+                                title = gdata.media.Title(text=uploadInfo.name),
+                                description = gdata.media.Description(text=uploadInfo.description),
+                                category = gdata.media.Category(text=uploadInfo.category),
+                                keywords = gdata.media.Keywords(text=','.join(uploadInfo.keywords)))
+
+            gvideo = self.service.InsertVideoEntry(
+                                self.gvideo,
+                                uploadInfo.url)
+            return Rid(uid=gvideo.id.text)
+        except Exception, e:
+            raise Exceptions.SyncronizeError("YouTube Upload Error.")
+
+    def _replace_video (self, uploadInfo):
+        raise Exceptions.NotSupportedError("FIXME: Not supported yet")
+
     def refresh(self):
-        DataProvider.DataSource.refresh(self)
+        DataProvider.TwoWay.refresh(self)
 
         self.entries = {}
         try:
-            feedUrl = ""
             if self.filter_type == 0:
                 videos = self._most_viewed ()
             elif self.filter_type == 1:
                 videos = self._top_rated ()
+            elif self.filter_type == 2:
+                videos = self._videos_upload_by (self.username)
             else:
-                if self.user_filter_type == 0:
-                    videos = self._videos_upload_by (self.username)
-                else:
-                    videos = self._favorite_videos (self.username)
+                videos = self._favorite_videos (self.username)
 
             for video in videos:
                 self.entries[video.title.text] = self._get_flv_video_url (video.link[0].href)
@@ -1341,7 +1387,7 @@
         return self.entries.keys()
 
     def get(self, LUID):
-        DataProvider.DataSource.get(self, LUID)
+        DataProvider.TwoWay.get(self, LUID)
         url = self.entries[LUID]
         log.debug("Title: '%s', Url: '%s'"%(LUID, url))
 
@@ -1352,24 +1398,68 @@
 
         return f
 
+    def put(self, video, overwrite, LUID=None):
+        """
+        Based off the ImageTwoWay put method.
+        Accepts a VFS file. Must be made local.
+        I also store a MD5 of the video's URI to check for duplicates
+        """
+        DataProvider.TwoWay.put(self, video, overwrite, LUID)
+
+        self._login()
+
+        originalName = video.get_filename()
+        #Gets the local URI (/foo/bar). If this is a remote file then
+        #it is first transferred to the local filesystem
+        videoURI = video.get_local_uri()
+        mimeType = video.get_mimetype()
+        keywords = video.get_tags ()
+        description = video.get_description()
+
+        uploadInfo = VideoUploadInfo(videoURI, mimeType, originalName, keywords, description)
+
+        #Check if we have already uploaded the video
+        if LUID != None:
+            url = self._get_video_info(LUID)
+            #Check if a video exists at that UID
+            if url != None:
+                if overwrite == True:
+                    #Replace the video
+                    return self._replace_video(LUID, uploadInfo)
+                else:
+                    #Only upload the video if it is newer than the remote one
+                    url = self._get_flv_video_url(url)
+                    remoteFile = File.File(url)
+
+                    #This is a limited test for equality type comparison
+                    comp = video.compare(remoteFile,True)
+                    log.debug("Compared %s with %s to check if they are the same (size). Result = %s" % 
+                            (video.get_filename(),remoteFile.get_filename(),comp))
+                    if comp != conduit.datatypes.COMPARISON_EQUAL:
+                        raise Exceptions.SynchronizeConflictError(comp, video, remoteFile)
+                    else:
+                        return conduit.datatypes.Rid(uid=LUID)
+
+        log.debug("Uploading video URI = %s, Mimetype = %s, Original Name = %s" % (videoURI, mimeType, originalName))
+
+        #Upload the file
+        return self._upload_video (uploadInfo)
+
     def finish(self, aborted, error, conflict):
-        DataProvider.DataSource.finish(self)
+        DataProvider.TwoWay.finish(self)
         self.files = None
 
     def get_configuration(self):
         return {
             "filter_type"       :   self.filter_type,
-            "user_filter_type"  :   self.user_filter_type,
+            "max_downloads"     :   self.max_downloads,
             "username"          :   self.username,
-            "max_downloads"     :   self.max_downloads
+            "password"          :   self.password
         }
 
     def get_UID(self):
         return Utils.get_user_string()
 
-    def _filter_user_toggled_cb (self, toggle, frame):
-        frame.set_sensitive(toggle.get_active())
-
     def _format_url (self, url):
         if self.max_downloads > 0:
             url = ("%s?max-results=%d" % (url, self.max_downloads))
@@ -1380,19 +1470,19 @@
         return service.Get(feed % params)
 
     def _top_rated(self):
-        url = self._format_url ("%s/top_rated" % YouTubeSource.STD_FEEDS)
+        url = self._format_url ("%s/top_rated" % YouTubeTwoWay.STD_FEEDS)
         return self._request(url).entry
 
     def _most_viewed(self):
-        url = self._format_url ("%s/most_viewed" % YouTubeSource.STD_FEEDS)
+        url = self._format_url ("%s/most_viewed" % YouTubeTwoWay.STD_FEEDS)
         return self._request(url).entry
 
     def _videos_upload_by(self, username):
-        url = self._format_url ("%s/%s/uploads" % (YouTubeSource.USERS_FEED, username))
+        url = self._format_url ("%s/%s/uploads" % (YouTubeTwoWay.USERS_FEED, username))
         return self._request(url).entry
 
     def _favorite_videos(self, username):
-        url = self._format_url ("%s/%s/favorites" % (YouTubeSource.USERS_FEED, username))
+        url = self._format_url ("%s/%s/favorites" % (YouTubeTwoWay.USERS_FEED, username))
         return self._request(url).entry
 
     # Generic extract step
@@ -1403,7 +1493,7 @@
         data = doc.read()
 
         # extract video name
-        match = YouTubeSource.VIDEO_NAME_RE.search(data)
+        match = YouTubeTwoWay.VIDEO_NAME_RE.search(data)
         if match is not None:
             video_name = match.group(1)
 
Index: conduit/modules/GoogleModule/youtube-config.glade
===================================================================
--- conduit/modules/GoogleModule/youtube-config.glade	(revision 1494)
+++ conduit/modules/GoogleModule/youtube-config.glade	(working copy)
@@ -1,423 +1,215 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--*- mode: xml -*-->
 <glade-interface>
-
-<widget class="GtkDialog" id="YouTubeSourceConfigDialog">
-  <property name="border_width">5</property>
-  <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-  <property name="title" translatable="yes">YouTube Source</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
-  <property name="modal">False</property>
-  <property name="resizable">False</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">2</property>
-
-      <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>
-	    <placeholder/>
-	  </child>
-	  
-	  <child>
-	    <widget class="GtkButton" id="button1">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="button2">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-ok</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-	    </widget>
-	  </child>
-
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkTable" id="table1">
-	  <property name="visible">True</property>
-	  <property name="n_rows">2</property>
-	  <property name="n_columns">2</property>
-	  <property name="homogeneous">False</property>
-	  <property name="row_spacing">5</property>
-	  <property name="column_spacing">5</property>
-
-	  <child>
-	    <widget class="GtkSpinButton" id="maxdownloads">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-	      <property name="climb_rate">1</property>
-	      <property name="digits">0</property>
-	      <property name="numeric">False</property>
-	      <property name="update_policy">GTK_UPDATE_ALWAYS</property>
-	      <property name="snap_to_ticks">False</property>
-	      <property name="wrap">False</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>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="label3">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Max retrieved videos (0 is unlimited):</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">False</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="left_attach">0</property>
-	      <property name="right_attach">1</property>
-	      <property name="top_attach">1</property>
-	      <property name="bottom_attach">2</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkFrame" id="frame1">
-	      <property name="visible">True</property>
-	      <property name="label_xalign">0</property>
-	      <property name="label_yalign">0.5</property>
-	      <property name="shadow_type">GTK_SHADOW_NONE</property>
-
-	      <child>
-		<widget class="GtkAlignment" id="alignment1">
-		  <property name="visible">True</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xscale">1</property>
-		  <property name="yscale">1</property>
-		  <property name="top_padding">0</property>
-		  <property name="bottom_padding">0</property>
-		  <property name="left_padding">12</property>
-		  <property name="right_padding">0</property>
-
-		  <child>
-		    <widget class="GtkVBox" id="vbox1">
-		      <property name="visible">True</property>
-		      <property name="homogeneous">False</property>
-		      <property name="spacing">5</property>
-
-		      <child>
-			<widget class="GtkRadioButton" id="mostviewed">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="label" translatable="yes">Most viewed</property>
-			  <property name="use_underline">True</property>
-			  <property name="relief">GTK_RELIEF_NORMAL</property>
-			  <property name="focus_on_click">True</property>
-			  <property name="active">True</property>
-			  <property name="inconsistent">False</property>
-			  <property name="draw_indicator">True</property>
-			</widget>
-			<packing>
-			  <property name="padding">0</property>
-			  <property name="expand">True</property>
-			  <property name="fill">True</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkRadioButton" id="toprated">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="label" translatable="yes">Top rated</property>
-			  <property name="use_underline">True</property>
-			  <property name="relief">GTK_RELIEF_NORMAL</property>
-			  <property name="focus_on_click">True</property>
-			  <property name="active">False</property>
-			  <property name="inconsistent">False</property>
-			  <property name="draw_indicator">True</property>
-			  <property name="group">mostviewed</property>
-			</widget>
-			<packing>
-			  <property name="padding">0</property>
-			  <property name="expand">True</property>
-			  <property name="fill">True</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkVBox" id="vbox3">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">5</property>
-
-			  <child>
-			    <widget class="GtkRadioButton" id="byuser">
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="label" translatable="yes">By user</property>
-			      <property name="use_underline">True</property>
-			      <property name="relief">GTK_RELIEF_NORMAL</property>
-			      <property name="focus_on_click">True</property>
-			      <property name="active">False</property>
-			      <property name="inconsistent">False</property>
-			      <property name="draw_indicator">True</property>
-			      <property name="group">mostviewed</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkFrame" id="frame">
-			      <property name="visible">True</property>
-			      <property name="sensitive">False</property>
-			      <property name="label_xalign">0</property>
-			      <property name="label_yalign">0.5</property>
-			      <property name="shadow_type">GTK_SHADOW_NONE</property>
-
-			      <child>
-				<widget class="GtkAlignment" id="alignment2">
-				  <property name="visible">True</property>
-				  <property name="xalign">0.5</property>
-				  <property name="yalign">0.5</property>
-				  <property name="xscale">1</property>
-				  <property name="yscale">1</property>
-				  <property name="top_padding">0</property>
-				  <property name="bottom_padding">0</property>
-				  <property name="left_padding">12</property>
-				  <property name="right_padding">0</property>
-
-				  <child>
-				    <widget class="GtkTable" id="table2">
-				      <property name="visible">True</property>
-				      <property name="n_rows">2</property>
-				      <property name="n_columns">2</property>
-				      <property name="homogeneous">False</property>
-				      <property name="row_spacing">5</property>
-				      <property name="column_spacing">5</property>
-
-				      <child>
-					<widget class="GtkHBox" id="hbox2">
-					  <property name="visible">True</property>
-					  <property name="homogeneous">False</property>
-					  <property name="spacing">0</property>
-
-					  <child>
-					    <widget class="GtkRadioButton" id="uploadedby">
-					      <property name="visible">True</property>
-					      <property name="can_focus">True</property>
-					      <property name="label" translatable="yes">Uploaded by</property>
-					      <property name="use_underline">True</property>
-					      <property name="relief">GTK_RELIEF_NORMAL</property>
-					      <property name="focus_on_click">True</property>
-					      <property name="active">True</property>
-					      <property name="inconsistent">False</property>
-					      <property name="draw_indicator">True</property>
-					    </widget>
-					    <packing>
-					      <property name="padding">0</property>
-					      <property name="expand">True</property>
-					      <property name="fill">True</property>
-					    </packing>
-					  </child>
-
-					  <child>
-					    <widget class="GtkRadioButton" id="favoritesof">
-					      <property name="visible">True</property>
-					      <property name="can_focus">True</property>
-					      <property name="label" translatable="yes">Favorites of</property>
-					      <property name="use_underline">True</property>
-					      <property name="relief">GTK_RELIEF_NORMAL</property>
-					      <property name="focus_on_click">True</property>
-					      <property name="active">False</property>
-					      <property name="inconsistent">False</property>
-					      <property name="draw_indicator">True</property>
-					      <property name="group">uploadedby</property>
-					    </widget>
-					    <packing>
-					      <property name="padding">0</property>
-					      <property name="expand">True</property>
-					      <property name="fill">True</property>
-					    </packing>
-					  </child>
-					</widget>
-					<packing>
-					  <property name="left_attach">1</property>
-					  <property name="right_attach">2</property>
-					  <property name="top_attach">0</property>
-					  <property name="bottom_attach">1</property>
-					</packing>
-				      </child>
-
-				      <child>
-					<widget class="GtkHBox" id="hbox1">
-					  <property name="visible">True</property>
-					  <property name="homogeneous">False</property>
-					  <property name="spacing">0</property>
-
-					  <child>
-					    <widget class="GtkLabel" id="label4">
-					      <property name="visible">True</property>
-					      <property name="label" translatable="yes">User: </property>
-					      <property name="use_underline">False</property>
-					      <property name="use_markup">False</property>
-					      <property name="justify">GTK_JUSTIFY_LEFT</property>
-					      <property name="wrap">False</property>
-					      <property name="selectable">False</property>
-					      <property name="xalign">0.5</property>
-					      <property name="yalign">0.5</property>
-					      <property name="xpad">0</property>
-					      <property name="ypad">0</property>
-					      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-					      <property name="width_chars">-1</property>
-					      <property name="single_line_mode">False</property>
-					      <property name="angle">0</property>
-					    </widget>
-					    <packing>
-					      <property name="padding">0</property>
-					      <property name="expand">False</property>
-					      <property name="fill">False</property>
-					    </packing>
-					  </child>
-
-					  <child>
-					    <widget class="GtkEntry" id="user">
-					      <property name="visible">True</property>
-					      <property name="can_focus">True</property>
-					      <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-					      <property name="editable">True</property>
-					      <property name="visibility">True</property>
-					      <property name="max_length">0</property>
-					      <property name="text" translatable="yes"></property>
-					      <property name="has_frame">True</property>
-					      <property name="invisible_char">●</property>
-					      <property name="activates_default">False</property>
-					    </widget>
-					    <packing>
-					      <property name="padding">0</property>
-					      <property name="expand">True</property>
-					      <property name="fill">True</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="x_options"></property>
-					</packing>
-				      </child>
-				    </widget>
-				  </child>
-				</widget>
-			      </child>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-			</widget>
-			<packing>
-			  <property name="padding">0</property>
-			  <property name="expand">True</property>
-			  <property name="fill">True</property>
-			</packing>
-		      </child>
-		    </widget>
-		  </child>
-		</widget>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label1">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;Donwload Videos&lt;/b&gt;</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="type">label_item</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="left_attach">0</property>
-	      <property name="right_attach">2</property>
-	      <property name="top_attach">0</property>
-	      <property name="bottom_attach">1</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
+  <widget class="GtkDialog" id="YouTubeTwoWayConfigDialog">
+    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">YouTube Source</property>
+    <property name="resizable">False</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</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="vbox1">
+            <property name="visible">True</property>
+            <child>
+              <widget class="GtkLabel" id="label2">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">&lt;b&gt;Account Details&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </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>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Username:</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkEntry" id="username">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label6">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Password:</property>
+                <property name="ellipsize">PANGO_ELLIPSIZE_START</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkEntry" id="password">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="visibility">False</property>
+              </widget>
+              <packing>
+                <property name="position">4</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">&lt;b&gt;Download Videos&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">5</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox2">
+                <property name="visible">True</property>
+                <property name="spacing">5</property>
+                <child>
+                  <widget class="GtkRadioButton" id="mostviewed">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Most viewed</property>
+                    <property name="use_underline">True</property>
+                    <property name="response_id">0</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkRadioButton" id="toprated">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Top rated</property>
+                    <property name="use_underline">True</property>
+                    <property name="response_id">0</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">mostviewed</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkRadioButton" id="uploadedby">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Uploaded by above user</property>
+                    <property name="use_underline">True</property>
+                    <property name="response_id">0</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">mostviewed</property>
+                  </widget>
+                  <packing>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkRadioButton" id="favoritesof">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">Favorites of above user</property>
+                    <property name="response_id">0</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">mostviewed</property>
+                  </widget>
+                  <packing>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">6</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label3">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Max retrieved videos (0 is unlimited):</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">7</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkSpinButton" id="maxdownloads">
+                <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="position">8</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>
+              <placeholder/>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="label">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-6</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button2">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="label">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-5</property>
+              </widget>
+              <packing>
+                <property name="position">2</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>
