Luis Montiel has proposed merging lp:~luismmontielg/do-plugins/YouTube into lp:do-plugins.
Requested reviews: Do Plugins Team (do-plugins) Fixed plugin, is working now, also changed namespace -- https://code.launchpad.net/~luismmontielg/do-plugins/YouTube/+merge/24958 Your team Do Plugins Team is requested to review the proposed merge of lp:~luismmontielg/do-plugins/YouTube into lp:do-plugins.
=== modified file '.bzrignore' --- .bzrignore 2010-05-08 01:02:38 +0000 +++ .bzrignore 2010-05-09 17:35:41 +0000 @@ -1,1 +1,3 @@ Emesene.addin.xml +.bzrignore +../Resources/Youtube.addin.xml === modified file 'YouTube/Makefile.am' --- YouTube/Makefile.am 2009-06-22 04:05:16 +0000 +++ YouTube/Makefile.am 2010-05-09 17:35:41 +0000 @@ -13,7 +13,8 @@ src/YouTubeSearchAction.cs \ src/YouTubeSubscriptionItem.cs \ src/YouTubeSubscriptionItemSource.cs \ - src/YoutubeVideoItem.cs + src/YoutubeVideoItem.cs \ + src/CertHandler.cs RESOURCES = \ Resources/Youtube.addin.xml \ === modified file 'YouTube/Resources/Youtube.addin.xml.in' --- YouTube/Resources/Youtube.addin.xml.in 2009-06-22 21:50:13 +0000 +++ YouTube/Resources/Youtube.addin.xml.in 2010-05-09 17:35:41 +0000 @@ -1,7 +1,7 @@ <Addin id="YouTube" namespace= "Do" - version="1.0" + version="1.1" name="YouTube" description="Search your favorites, subscriptions, uploaded videos, and more." author="Luis Miguel Montiel G" @@ -22,11 +22,11 @@ <!-- Extensions included in this assembly --> <!-- Sources --> <Extension path = "/Do/ItemSource"> - <ItemSource type="Do.Universe.YouTubeFavoriteItemSource" /> - <ItemSource type="Do.Universe.YouTubeSubscriptionItemSource" /> - <ItemSource type="Do.Universe.YouTubeOwnVideosItemSource" /> + <ItemSource type="Youtube.YouTubeFavoriteItemSource" /> + <ItemSource type="Youtube.YouTubeSubscriptionItemSource" /> + <ItemSource type="Youtube.YouTubeOwnVideosItemSource" /> </Extension> <Extension path = "/Do/Action"> - <Action type="Do.Universe.YouTubeSearchAction" /> + <Action type="Youtube.YouTubeSearchAction" /> </Extension> </Addin> === added file 'YouTube/src/CertHandler.cs' --- YouTube/src/CertHandler.cs 1970-01-01 00:00:00 +0000 +++ YouTube/src/CertHandler.cs 2010-05-09 17:35:41 +0000 @@ -0,0 +1,37 @@ +/* CertHandler.cs + * + * GNOME Do is the legal property of its developers. Please refer to the + * COPYRIGHT file distributed with this + * source distribution. + * + * 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/>. + */ + +using System; +using System.Net; +using System.Collections; +using System.Security.Cryptography.X509Certificates; + +namespace Youtube +{ + + public class CertHandler : ICertificatePolicy + { + public bool CheckValidationResult (ServicePoint sp, X509Certificate cert, + WebRequest request, int error) + { + return true; + } + } +} === modified file 'YouTube/src/Preferences.cs' --- YouTube/src/Preferences.cs 2009-06-22 04:05:16 +0000 +++ YouTube/src/Preferences.cs 2010-05-09 17:35:41 +0000 @@ -1,8 +1,28 @@ +/* Preferences.cs + * + * GNOME Do is the legal property of its developers. Please refer to the + * COPYRIGHT file distributed with this + * source distribution. + * + * 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/>. + */ + using System; using Mono.Addins; using Do.Platform; -namespace Do.Universe +namespace Youtube { public class YouTubePreferences { === modified file 'YouTube/src/YouTubeFavoriteItemSource.cs' --- YouTube/src/YouTubeFavoriteItemSource.cs 2009-06-22 04:05:16 +0000 +++ YouTube/src/YouTubeFavoriteItemSource.cs 2010-05-09 17:35:41 +0000 @@ -1,3 +1,23 @@ +/* YouTubeFavoriteItemSource.cs + * + * GNOME Do is the legal property of its developers. Please refer to the + * COPYRIGHT file distributed with this + * source distribution. + * + * 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/>. + */ + using System; using System.Collections.Generic; using Mono.Addins; @@ -6,7 +26,7 @@ using Do.Platform.Linux; using System.Threading; -namespace Do.Universe +namespace Youtube { public class YouTubeFavoriteItemSource : ItemSource, IConfigurable { === modified file 'YouTube/src/YouTubeOwnVideosItemSource.cs' --- YouTube/src/YouTubeOwnVideosItemSource.cs 2009-06-22 04:05:16 +0000 +++ YouTube/src/YouTubeOwnVideosItemSource.cs 2010-05-09 17:35:41 +0000 @@ -1,8 +1,22 @@ -// YouTubeOwnVideosSource.cs created with MonoDevelop -// User: luis at 08:50 p 10/09/2008 -// -// To change standard headers go to Edit->Preferences->Coding->Standard Headers -// +/* YouTubeOwnVideosItemSource.cs + * + * GNOME Do is the legal property of its developers. Please refer to the + * COPYRIGHT file distributed with this + * source distribution. + * + * 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/>. + */ using System; using System.Collections.Generic; @@ -10,7 +24,7 @@ using System.Threading; using Do.Universe; -namespace Do.Universe +namespace Youtube { === modified file 'YouTube/src/YouTubeSearchAction.cs' --- YouTube/src/YouTubeSearchAction.cs 2009-02-01 20:19:36 +0000 +++ YouTube/src/YouTubeSearchAction.cs 2010-05-09 17:35:41 +0000 @@ -1,10 +1,30 @@ +/* YouTubeSearchAction.cs + * + * GNOME Do is the legal property of its developers. Please refer to the + * COPYRIGHT file distributed with this + * source distribution. + * + * 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/>. + */ + using System; using System.Collections.Generic; using Do.Universe; using Do.Platform; using System.Linq; -namespace Do.Universe +namespace Youtube { public class YouTubeSearchAction : Act { @@ -39,22 +59,9 @@ public override IEnumerable<Item> Perform (IEnumerable<Item> items, IEnumerable<Item> modItems) { - - //string search = ""; - -// foreach (Item item in items) { -// if (item is IUrlItem) { -// search = (item as IUrlItem).Url; -// } else if (item is ITextItem) { -// search = (item as ITextItem).Text; -// } -// search = search.Replace (" ", "%20"); -// Services.Environment.OpenUrl(url+search); -// } - string search = (items.First() as ITextItem).Text; search = search.Replace (" ", "%20"); - Services.Environment.OpenUrl(Youtube.searchUrl+search); + Services.Environment.OpenUrl(String.Format(Youtube.searchUrl, search)); yield break; } } === modified file 'YouTube/src/YouTubeSubscriptionItem.cs' --- YouTube/src/YouTubeSubscriptionItem.cs 2009-02-01 20:19:36 +0000 +++ YouTube/src/YouTubeSubscriptionItem.cs 2010-05-09 17:35:41 +0000 @@ -1,7 +1,28 @@ +/* YouTubeSubscriptionItem.cs + * + * GNOME Do is the legal property of its developers. Please refer to the + * COPYRIGHT file distributed with this + * source distribution. + * + * 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/>. + */ + + using System; using Do.Universe; -namespace Do.Universe +namespace Youtube { public class YouTubeSubscriptionItem : Item, IUrlItem { === modified file 'YouTube/src/YouTubeSubscriptionItemSource.cs' --- YouTube/src/YouTubeSubscriptionItemSource.cs 2009-06-22 04:05:16 +0000 +++ YouTube/src/YouTubeSubscriptionItemSource.cs 2010-05-09 17:35:41 +0000 @@ -1,10 +1,31 @@ +/* YouTubeSubscriptionItemSource.cs + * + * GNOME Do is the legal property of its developers. Please refer to the + * COPYRIGHT file distributed with this + * source distribution. + * + * 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/>. + */ + + using System; using System.Collections.Generic; using Mono.Addins; using System.Threading; using Do.Universe; -namespace Do.Universe +namespace Youtube { public class YouTubeSubscriptionItemSource : ItemSource { === modified file 'YouTube/src/Youtube.cs' --- YouTube/src/Youtube.cs 2009-06-22 04:05:16 +0000 +++ YouTube/src/Youtube.cs 2010-05-09 17:35:41 +0000 @@ -1,3 +1,23 @@ +/* Youtube.cs + * + * GNOME Do is the legal property of its developers. Please refer to the + * COPYRIGHT file distributed with this + * source distribution. + * + * 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/>. + */ + using System; using System.IO; using System.Net; @@ -10,119 +30,127 @@ using Google.GData.YouTube; using Google.GData.Extensions.MediaRss; -namespace Do.Universe +namespace Youtube { public class Youtube { static readonly string ConnectionErrorMessage = AddinManager.CurrentLocalizer.GetString ("An error occurred connecting to YouTube, " + "are your credentials valid?"); - + static readonly string MissingCredentialsMessage = AddinManager.CurrentLocalizer.GetString ("Missing login credentials. Please set " + "login information in YouTube plugin configuration."); - - public const string appName = "luismmontielg-gnomeDoYoutubePlugin0.1"; - public const string searchUrl = "http://www.youtube.com/results?search_query="; - public static string clientID = "ytapi-lmg-test-ojd8d285-0"; - public static string developerKey = "AI39si5c61jYzQLvzEDjAnU1HOQIf-DzyzvIBXAkGJ82NlXoMg10RDW1sRz5Uyodv9_ETPzmJXdfFqVRNt51yGkkNo2YW0BdxQ"; + + private const string appName = "gnome-do-plugin"; + public const string searchUrl = "http://www.youtube.com/results?search_query={0}"; + private const string clientID = "gnome-do-client"; + private const string developerKey = "AI39si5utjLEVOmAty2JLxz8KlixVQkwbSsEZqUXVUV-hUK1zDctrUbujGL2kWJBs47a7CaO-LOf_FXUiyuvQ9j7pbq8YO9wsA"; + public static List<Item> favorites; public static List<Item> subscriptions; public static List<Item> own; + private static YouTubeService service; private static string username; private static string password; + private static int subUpdate; private static int favUpdate; private static int ownUpdate; - + + private const string favoritesQueryTemplate = "http://gdata.youtube.com/feeds/api/users/default/favorites?start-index={0}&max-results={1}"; + private const string ownQueryTemplate = "http://gdata.youtube.com/feeds/api/users/default/uploads?start-index={0}&max-results={1}"; + private const string youtubeWatchUrlTemplate = "http://www.youtube.com/watch?v={0}"; + public static YouTubePreferences Preferences { get; private set; } - + static Youtube() { Youtube.favorites = new List<Item>(); Youtube.own = new List<Item>(); Youtube.subscriptions = new List<Item>(); + Preferences = new YouTubePreferences (); + subUpdate = 0; favUpdate = 0; ownUpdate = 0; + username = Preferences.Username; password = Preferences.Password; + Connect (username, password); } - + + private static void parseFeed(YouTubeFeed feed, List<Item> videos) + { + string description = ""; + string url = null; + foreach(YouTubeEntry entry in feed.Entries) + { + description = ""; + url = String.Format(youtubeWatchUrlTemplate, entry.VideoId); + if (entry.Media.Description != null) + { + description = entry.Media.Description.Value; + } + YoutubeVideoItem video = new YoutubeVideoItem(entry.Title.Text, url, description); + videos.Add(video); + } + } + + private static void update(string queryTemplate, List<Item> videos, ref int counter, string category) + { + if (videos.Count != 0 || (counter % 20 != 0 && counter != 0)) + { + counter = counter + 1; + return; + } + + counter = counter + 1; + + videos.Clear(); + int maxResults = 50; + int startIndex = 1; + + string feedUrl = String.Format(queryTemplate, startIndex, maxResults); + + YouTubeQuery query = new YouTubeQuery(feedUrl); + YouTubeFeed videoFeed = null; + + try + { + videoFeed = service.Query(query); + while(videoFeed.Entries.Count > 0) + { + parseFeed(videoFeed, videos); + + startIndex += maxResults; + feedUrl = String.Format(queryTemplate, startIndex, maxResults); + query = new YouTubeQuery(feedUrl); + videoFeed = service.Query(query); + } + startIndex = 1; + Log<Youtube>.Debug("Finished updating {0} videos", category); + } + catch(Exception e) + { + Log<Youtube>.Error ("Error getting {0} videos - {1}", category, e.Message); + Log<Youtube>.Debug (e.StackTrace); + } + + } + public static void updateFavorites() { - favUpdate++; - Log<Youtube>.Debug("Update favorites videos tries = {0} - favorite.Count : {1}", favUpdate, Youtube.favorites.Count); - if (Youtube.favorites.Count == 0 || favUpdate%20 == 0){ - Youtube.favorites.Clear(); - int maxResults = 50; - int startIndex = 1; - - string feedUrl = "http://gdata.youtube.com/feeds/api/users/"+ username +"/favorites?start-index="+ startIndex +"&max-results="+maxResults; - YouTubeQuery query = new YouTubeQuery(feedUrl); - Log<Youtube>.Debug("feedUrl for favorites videos: {0}", feedUrl); - try{ - YouTubeFeed videoFeed = service.Query(query); - while(videoFeed.Entries.Count > 0){ - foreach (YouTubeEntry entry in videoFeed.Entries) - { - //Log<Youtube>.Debug("Video #{0}, Title: {1}", ++i, entry.Title.Text); - string url = ("http://www.youtube.com/watch?v="+entry.VideoId); - //Log<Youtube>.Debug("Video url: {0}", url); - YoutubeVideoItem video = new YoutubeVideoItem(entry.Title.Text, url, entry.Media.Description.Value); - favorites.Add(video); - } - startIndex += maxResults; - feedUrl = "http://gdata.youtube.com/feeds/api/users/"+ username +"/favorites?start-index="+ startIndex +"&max-results="+maxResults; - query = new YouTubeQuery(feedUrl); - videoFeed = service.Query(query); - } - startIndex = 1; - Log<Youtube>.Debug("Finished updating favorite videos"); - }catch(Exception e) { - Log<Youtube>.Error ("Error getting favorites videos - {0}", e.Message); - Log<Youtube>.Debug (e.StackTrace); - } - } + update (favoritesQueryTemplate, Youtube.favorites, ref favUpdate, "favorites"); } - + public static void updateOwn() { - ownUpdate++; - Log<Youtube>.Debug("Update own videos tries = {0} - own.Count : {1}", ownUpdate, Youtube.own.Count); - if (Youtube.own.Count == 0 || ownUpdate%20 == 0){ - Youtube.own.Clear(); - int maxResults = 50; - int startIndex = 1; - - string feedUrl = "http://gdata.youtube.com/feeds/api/users/"+ username +"/uploads?start-index="+ startIndex +"&max-results="+maxResults; - YouTubeQuery query = new YouTubeQuery(feedUrl); - Log<Youtube>.Debug("feedUrl for own videos: {0}", feedUrl); - try{ - YouTubeFeed videoFeed = service.Query(query); - while(videoFeed.Entries.Count > 0){ - foreach (YouTubeEntry entry in videoFeed.Entries) - { - //Log<Youtube>.Debug("Video #{0}, Title(own video): {1}", ++i, entry.Title.Text); - string url = "http://www.youtube.com/watch?v="+entry.VideoId; - YoutubeVideoItem video = new YoutubeVideoItem(entry.Title.Text, url, entry.Media.Description.Value); - own.Add(video); - } - startIndex += maxResults; - feedUrl = "http://gdata.youtube.com/feeds/api/users/"+ username +"/uploads?start-index="+ startIndex +"&max-results="+maxResults; - query = new YouTubeQuery(feedUrl); - videoFeed = service.Query(query); - } - Log<Youtube>.Debug("Finished updating own videos"); - }catch(Exception e) { - Log<Youtube>.Error ("Error getting own videos - {0}", e.Message); - Log<Youtube>.Debug (e.StackTrace); - } - } - } - + update (ownQueryTemplate, Youtube.own, ref ownUpdate, "own youtube"); + } + public static void updateSubscriptions() { subUpdate++; @@ -130,19 +158,19 @@ if (Youtube.subscriptions.Count == 0 || subUpdate%20==0){ Youtube.subscriptions.Clear(); - string feedUrl = "http://gdata.youtube.com/feeds/api/users/"+ username +"/subscriptions"; + string feedUrl = "http://gdata.youtube.com/feeds/api/users/default/subscriptions"; YouTubeQuery query = new YouTubeQuery(feedUrl); Log<Youtube>.Debug("feedUrl for subscriptions: {0}", feedUrl); + SubscriptionFeed subFeed = null; + string url = "http://www.youtube.com/user/{0}"; try { - SubscriptionFeed subFeed = service.GetSubscriptions(query); + subFeed = service.GetSubscriptions(query); if(subFeed.Entries.Count > 0){ foreach (SubscriptionEntry entry in subFeed.Entries) { - //Log<Youtube>.Debug("Subscriptions - {0}", ++i); - //Log<Youtube>.Debug("{0}", entry.Title.Text); - string url = "http://www.youtube.com/user/" + entry.UserName; - YouTubeSubscriptionItem subscription = new YouTubeSubscriptionItem(entry.UserName, url, entry.Title.Text); + YouTubeSubscriptionItem subscription = + new YouTubeSubscriptionItem(entry.UserName, String.Format(url, entry.UserName), entry.Title.Text); Youtube.subscriptions.Add(subscription); } } @@ -150,12 +178,14 @@ } catch(Exception e) { - Log<Youtube>.Error ("Error getting subscriptions - {0}", e.Message); - Log<Youtube>.Debug (e.StackTrace); + Log<Youtube>.Error ("Error getting subscriptions - {0}", e.Message); + Log<Youtube>.Debug (e.StackTrace); } } - } - + } + + + public static bool TryConnect (string username, string password) { try { @@ -180,8 +210,10 @@ try { service = new YouTubeService (appName, clientID, developerKey); service.setUserCredentials (username, password); + ServicePointManager.CertificatePolicy = new CertHandler (); } catch (Exception e) { Log<Youtube>.Error (ConnectionErrorMessage); + Log<Youtube>.Error (e.Message); } } } === modified file 'YouTube/src/YoutubeConfig.cs' --- YouTube/src/YoutubeConfig.cs 2009-02-01 20:19:36 +0000 +++ YouTube/src/YoutubeConfig.cs 2010-05-09 17:35:41 +0000 @@ -1,9 +1,29 @@ +/* YoutubeConfig.cs + * + * GNOME Do is the legal property of its developers. Please refer to the + * COPYRIGHT file distributed with this + * source distribution. + * + * 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/>. + */ + using System; using Gtk; using Do.Platform; using Do.Platform.Linux; -namespace Do.Universe +namespace Youtube { public class YouTubeConfig : AbstractLoginWidget === modified file 'YouTube/src/YoutubeVideoItem.cs' --- YouTube/src/YoutubeVideoItem.cs 2009-02-01 20:19:36 +0000 +++ YouTube/src/YoutubeVideoItem.cs 2010-05-09 17:35:41 +0000 @@ -1,7 +1,27 @@ +/* YouTubeVideoItem.cs + * + * GNOME Do is the legal property of its developers. Please refer to the + * COPYRIGHT file distributed with this + * source distribution. + * + * 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/>. + */ + using System; using Do.Universe; -namespace Do.Universe +namespace Youtube { public class YoutubeVideoItem : Item, IUrlItem { @@ -35,6 +55,5 @@ { get { return url; } } - } }
_______________________________________________ Mailing list: https://launchpad.net/~do-plugins Post to : [email protected] Unsubscribe : https://launchpad.net/~do-plugins More help : https://help.launchpad.net/ListHelp

