~vanvugt/ubuntu/oneiric/mediatomb/fix-770964-784431

« back to all changes in this revision

Viewing changes to src/youtube_service.cc

  • Committer: Bazaar Package Importer
  • Author(s): Andres Mejia
  • Date: 2009-04-22 21:39:19 UTC
  • mto: (4.2.1 sid)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20090422213919-52m015y6gcpv1m1g
Tags: upstream-0.12.0~svn2018
ImportĀ upstreamĀ versionĀ 0.12.0~svn2018

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
    Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>,
8
8
                       Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>
9
9
    
10
 
    Copyright (C) 2006-2008 Gena Batyan <bgeradz@mediatomb.cc>,
 
10
    Copyright (C) 2006-2009 Gena Batyan <bgeradz@mediatomb.cc>,
11
11
                            Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>,
12
12
                            Leonhard Wimmer <leo@mediatomb.cc>
13
13
    
24
24
    version 2 along with MediaTomb; if not, write to the Free Software
25
25
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
26
26
    
27
 
    $Id: youtube_service.cc 1717 2008-03-01 19:25:05Z jin_eld $
 
27
    $Id: youtube_service.cc 2010 2009-01-11 19:10:43Z lww $
28
28
*/
29
29
 
30
30
/// \file youtube_service.cc
37
37
 
38
38
#include "zmm/zmm.h"
39
39
#include "youtube_service.h"
40
 
#include "youtube_content_handler.h"
41
40
#include "content_manager.h"
42
41
#include "string_converter.h"
43
42
#include "config_manager.h"
48
47
using namespace zmm;
49
48
using namespace mxml;
50
49
 
51
 
// REST API defines
52
 
 
53
50
// Base request URL
54
 
#define REST_BASE_URL                   "http://www.youtube.com/api2_rest?"
55
 
 
56
 
// REST API methods
57
 
// dev_id=dev_id&user=user
58
 
#define REST_METHOD_LIST_FAVORITE       "youtube.users.list_favorite_videos"
59
 
 
60
 
// dev_id=dev_id&tag=tag&page=page&per_page=per_page
61
 
#define REST_METHOD_LIST_BY_TAG         "youtube.videos.list_by_tag"
62
 
 
63
 
// dev_id=dev_id&user=user&page=page&per_page=per_page
64
 
#define REST_METHOD_LIST_BY_USER        "youtube.videos.list_by_user"
65
 
 
66
 
// dev_id=dev_id
67
 
#define REST_METHOD_LIST_FEATURED       "youtube.videos.list_featured"
68
 
 
69
 
// dev_id=dev_id&id=id&page=page&per_page=per_page
70
 
#define REST_METHOD_LIST_BY_PLAYLIST    "youtube.videos.list_by_playlist"
71
 
 
72
 
// dev_id=dev_id&time_range=time_range
73
 
#define REST_METHOD_LIST_POPULAR        "youtube.videos.list_popular"
74
 
 
75
 
// dev_id=dev_id& category_id=category_id &tag=tag&page=page&per_page=per_page
76
 
#define REST_METHOD_LIST_BY_CAT_AND_TAG "youtube.videos.list_by_category_and_tag"
77
 
// REST API parameters
78
 
#define REST_PARAM_DEV_ID                   "dev_id"
79
 
#define REST_PARAM_TAG                      "tag"
80
 
#define REST_PARAM_ITEMS_PER_PAGE           "per_page"
81
 
#define REST_PARAM_PAGE_NUMBER              "page"
82
 
#define REST_PARAM_USER                     "user"
83
 
#define REST_PARAM_METHOD                   "method"
84
 
#define REST_PARAM_PLAYLIST_ID              "id"
85
 
#define REST_PARAM_CATEGORY_ID              "category_id"
86
 
#define REST_PARAM_TIME_RANGE               "time_range"
87
 
 
88
 
// REST API time range values
89
 
#define REST_VALUE_TIME_RANGE_ALL           "all"
90
 
#define REST_VALUE_TIME_RANGE_DAY           "day"
91
 
#define REST_VALUE_TIME_RANGE_WEEK          "week"
92
 
#define REST_VALUE_TIME_RANGE_MONTH         "month"
93
 
 
94
 
// REST API available categories
95
 
// categories are now handled in the enum
96
 
/*
97
 
#define REST_VALUE_CAT_FILM_AND_ANIMATION   "1"
98
 
#define REST_VALUE_CAT_AUTOS_AND_VEHICLES   "2"
99
 
#define REST_VALUE_CAT_COMEDY               "23"
100
 
#define REST_VALUE_CAT_ENTERTAINMENT        "24"
101
 
#define REST_VALUE_CAT_MUSIC                "10"
102
 
#define REST_VALUE_CAT_NEWS_AND_POLITICS    "25"
103
 
#define REST_VALUE_CAT_PEOPLE_AND_BLOGS     "22"
104
 
#define REST_VALUE_CAT_PETS_AND_ANIMALS     "15"
105
 
#define REST_VALUE_CAT_HOWTO_AND_DIY        "26"
106
 
#define REST_VALUE_CAT_SPORTS               "17"
107
 
#define REST_VALUE_CAT_TRAVEL_AND_PLACES    "19"
108
 
#define REST_VALUE_CAT_GADGETS_AND_GAMES    "20"
109
 
*/
 
51
#define GDATA_API_YT_BASE_URL           "http://gdata.youtube.com/feeds/api/"
 
52
 
 
53
// /users/USERNAME/favorites
 
54
#define GDATA_REQUEST_USERS                    "users/"
 
55
#define GDATA_REQUEST_FAVORITES                "/favorites"
 
56
#define GDATA_REQUEST_SUBSCRIPTIONS            "/subscriptions"
 
57
#define GDATA_REQUEST_PLAYLISTS                "/playlists"
 
58
#define GDATA_REQUEST_UPLOADS                  "/uploads"
 
59
// /feeds/api/videos?vq="SEARCH TERMS"
 
60
#define GDATA_REQUEST_SEARCH                   "videos"
 
61
 
 
62
// all stdfeeds:  "/standardfeeds/REGION_ID/feed"
 
63
#define GDATA_REQUEST_STDFEED_BASE              "standardfeeds"
 
64
 
 
65
#define GDATA_REQUEST_STDFEED_TOP_RATED         "top_rated"
 
66
#define GDATA_REQUEST_STDFEED_TOP_FAVORITES     "top_favorites"
 
67
#define GDATA_REQUEST_STDFEED_MOST_VIEWED       "most_viewed"
 
68
#define GDATA_REQUEST_STDFEED_MOST_RECENT       "most_recent"
 
69
#define GDATA_REQUEST_STDFEED_MOST_DISCUSSED    "most_discussed"
 
70
#define GDATA_REQUEST_STDFEED_MOST_LINKED       "most_linked"
 
71
#define GDATA_REQUEST_STDFEED_MOST_RESPONDED    "most_responded"
 
72
#define GDATA_REQUEST_STDFEED_RECENTLY_FEATURED "recently_featured"
 
73
#define GDATA_REQUEST_STDFEED_WATCH_ON_MOBILE   "watch_on_mobile"
 
74
 
 
75
static const char *YT_stdfeeds[] = 
 
76
{
 
77
    GDATA_REQUEST_STDFEED_TOP_RATED,        // has time
 
78
    GDATA_REQUEST_STDFEED_TOP_FAVORITES,    // has time
 
79
    GDATA_REQUEST_STDFEED_MOST_VIEWED,      // has time
 
80
    GDATA_REQUEST_STDFEED_MOST_RECENT,      
 
81
    GDATA_REQUEST_STDFEED_MOST_DISCUSSED,   // has time
 
82
    GDATA_REQUEST_STDFEED_MOST_LINKED,      // has time
 
83
    GDATA_REQUEST_STDFEED_MOST_RESPONDED,   // has time
 
84
    GDATA_REQUEST_STDFEED_RECENTLY_FEATURED,
 
85
    GDATA_REQUEST_STDFEED_WATCH_ON_MOBILE,
 
86
    NULL,
 
87
};
 
88
 
 
89
// gdata default parameters
 
90
//http://code.google.com/apis/youtube/reference.html#Query_parameter_definitions
 
91
#define GDATA_PARAM_FEED_FORMAT          "alt"
 
92
 
 
93
// additional YT specific parameters
 
94
#define GDATA_YT_PARAM_VIDEO_QUERY          "vq" // value must be url escaped
 
95
#define GDATA_YT_PARAM_ORDERBY              "orderby"
 
96
#define GDATA_YT_PARAM_FORMAT               "format"
 
97
#define GDATA_YT_PARAM_RESTRICT_LANGUAGE    "lr"
 
98
#define GDATA_YT_PARAM_RESTRICTED_CONTENT   "racy"
 
99
#define GDATA_YT_PARAM_COUNTRY_RESTRICTION  "restriction"
 
100
#define GDATA_YT_PARAM_TIME                 "time"
 
101
#define GDATA_YT_PARAM_AUTHOR               "author"
 
102
 
 
103
#define GDATA_YT_PARAM_START_INDEX          "start-index"
 
104
#define GDATA_YT_PARAM_MAX_RESULTS_PER_REQ  "max-results"
 
105
#define GDATA_YT_MAXIMUM_ALLOWED_RESULTS    1000
 
106
 
 
107
// allowed parameter values
 
108
#define GDATA_VALUE_FEED_FORMAT_RSS         "rss"
 
109
 
 
110
#define GDATA_YT_VALUE_ORDERBY_RELEVANCE    "relevance"
 
111
#define GDATA_YT_VALUE_ORDERBY_PUBLISHED    "published"
 
112
#define GDATA_YT_VALUE_ORDERBY_VIEWCOUNT    "viewCount"
 
113
#define GDATA_YT_VALUE_ORDERBY_RATING       "rating"
 
114
/// \todo relevance_lang_languageCode
 
115
 
 
116
#define GDATA_YT_VALUE_FORMAT_SWF           "5"
 
117
/// \todo do we need rtsp stuff? resolution is quite small there
 
118
 
 
119
// time range values
 
120
#define GDATA_YT_VALUE_TIME_RANGE_ALL       "all_time"
 
121
#define GDATA_YT_VALUE_TIME_RANGE_DAY       "today"
 
122
#define GDATA_YT_VALUE_TIME_RANGE_WEEK      "this_week"
 
123
#define GDATA_YT_VALUE_TIME_RANGE_MONTH     "this_month"
110
124
 
111
125
// REST API min/max items per page values
112
 
#define REST_VALUE_PER_PAGE_MIN             "1" // allthouth the spec says 20,
113
 
                                                // lower values also seem to 
114
 
                                                // work
115
 
#define REST_VALUE_PER_PAGE_MAX             "100"
116
 
 
117
 
#define AMOUNT_ALL                          (-333)
118
 
#define PER_PAGE_MIN                        1
119
 
#define PER_PAGE_MAX                        100
120
 
 
121
 
// REST API error codes
122
 
#define REST_ERROR_INTERNAL                 "1"
123
 
#define REST_ERROR_BAD_XMLRPC               "2"
124
 
#define REST_ERROR_UNKOWN_PARAM             "3"
125
 
#define REST_ERROR_MISSING_REQURED_PARAM    "4"
126
 
#define REST_ERROR_MISSING_METHOD           "5"
127
 
#define REST_ERROR_UNKNOWN_METHOD           "6"
128
 
#define REST_ERROR_MISSING_DEV_ID           "7"
129
 
#define REST_ERROR_BAD_DEV_ID               "8"
130
 
#define REST_ERROR_NO_SUCH_USER             "101"
131
 
 
132
 
#define CAT_NAME_FILM_AND_ANIM              "Film & Animation"
133
 
#define CAT_NAME_AUTOS_AND_VEHICLES         "Autos & Vehicles"
 
126
#define GDATA_YT_VALUE_START_INDEX_MIN      "1"
 
127
#define GDATA_YT_VALUE_PER_PAGE_MAX         "50"
 
128
 
 
129
#define GDATA_YT_VALUE_RACY_ON              "include"
 
130
#define GDATA_YT_VALUE_RACY_OFF             "exclude"
 
131
 
 
132
#define AMOUNT_ALL                          (1000) // max items that we can get
 
133
 
 
134
#define CAT_NAME_FILM                       "Film & Animation"
 
135
#define CAT_NAME_AUTOS                      "Autos & Vehicles"
134
136
#define CAT_NAME_COMEDY                     "Comedy"
135
137
#define CAT_NAME_ENTERTAINMENT              "Entertainment"
136
138
#define CAT_NAME_MUSIC                      "Music"
137
 
#define CAT_NAME_NEWS_AND_POLITICS          "News & Politics"
138
 
#define CAT_NAME_PEOPLE_AND_BLOGS           "People & Blogs"
139
 
#define CAT_NAME_PETS_AND_ANIMALS           "Pets & Animals"
140
 
#define CAT_NAME_HOWTO_AND_DIY              "Howto & DIY" 
 
139
#define CAT_NAME_NEWS                       "News & Politics"
 
140
#define CAT_NAME_PEOPLE                     "People & Blogs"
 
141
#define CAT_NAME_ANIMALS                    "Pets & Animals"
 
142
#define CAT_NAME_HOWTO                      "Howto & Style" 
141
143
#define CAT_NAME_SPORTS                     "Sports"
142
 
#define CAT_NAME_TRAVEL_AND_PLACES          "Travel & Places"
143
 
#define CAT_NAME_GADGETS_AND_GAMES          "Gadgets & Games"
 
144
#define CAT_NAME_TRAVEL                     "Travel & Events"
 
145
#define CAT_NAME_GADGETS                    "Gadgets & Games"
 
146
#define CAT_NAME_SHORT_MOVIES               "Short Movies"
 
147
#define CAT_NAME_VIDEOBLOG                  "Videoblogging"
 
148
#define CAT_NAME_EDUCATION                  "Education"
 
149
#define CAT_NAME_NONPROFIT                  "Nonprofits & Activism"
144
150
 
 
151
#define REQ_NAME_STDFEEDS                   "Standard Feeds"
 
152
#define REQ_NAME_VIDEO_SEARCH               "Video Queries"
145
153
#define REQ_NAME_FAVORITES                  "Favorites"
146
 
#define REQ_NAME_FEATURED                   "Featured"
147
 
#define REQ_NAME_POPULAR                    "Popular"
148
 
#define REQ_NAME_PLAYLIST                   "Playlists"
149
 
#define REQ_NAME_CATEGORY_AND_TAG           "Categories"
150
 
// custom names
151
 
#define REQ_NAME_BY_USER                    "User"
152
 
#define REQ_NAME_BY_TAG                     "Tag"
 
154
#define REQ_NAME_PLAYLISTS                  "Playlists"
 
155
#define REQ_NAME_SUBSCRIPTIONS              "Subscriptions"
 
156
#define REQ_NAME_UPLOADS                    "User Videos"
153
157
 
154
158
// config.xml defines
155
 
#define CFG_CAT_STRING_FILM_AND_ANIM       "films_and_animation"
156
 
#define CFG_CAT_STRING_AUTOS_AND_VEHICLES   "autos_and_vehicles"
157
 
#define CFG_CAT_STRING_COMEDY               "comedy"
158
 
#define CFG_CAT_STRING_ENTERTAINMENT        "entertainment"
159
 
#define CFG_CAT_STRING_MUSIC                "music"
160
 
#define CFG_CAT_STRING_NEWS_AND_POLITICS    "news_and_politics"
161
 
#define CFG_CAT_STRING_PEOPLE_AND_BLOGS     "people_and_blogs"
162
 
#define CFG_CAT_STRING_PETS_AND_ANIMALS     "pets_and_animals"
163
 
#define CFG_CAT_STRING_HOWTO_AND_DIY        "howto_and_diy"
164
 
#define CFG_CAT_STRING_SPORTS               "sports"
165
 
#define CFG_CAT_STRING_TRAVEL_AND_PLACES    "travel_and_places"
166
 
#define CFG_CAT_STRING_GADGETS_AND_GAMES    "gadgets_and_games"
 
159
#define CFG_CAT_TERM_FILM                   "Film"
 
160
#define CFG_CAT_TERM_AUTOS                  "Autos"
 
161
#define CFG_CAT_TERM_MUSIC                  "Music"
 
162
#define CFG_CAT_TERM_ANIMALS                "Animals"
 
163
#define CFG_CAT_TERM_SPORTS                 "Sports"
 
164
#define CFG_CAT_TERM_TRAVEL                 "Travel"
 
165
#define CFG_CAT_TERM_SHORT_MOVIES           "Shortmov"
 
166
#define CFG_CAT_TERM_VIDEOBLOG              "Videoblog"
 
167
#define CFG_CAT_TERM_GADGETS                "Games"
 
168
#define CFG_CAT_TERM_COMEDY                 "Comedy"
 
169
#define CFG_CAT_TERM_PEOPLE                 "People"
 
170
#define CFG_CAT_TERM_NEWS                   "News"
 
171
#define CFG_CAT_TERM_ENTERTAINMENT          "Entertainment"
 
172
#define CFG_CAT_TERM_EDUCATION              "Education"
 
173
#define CFG_CAT_TERM_HOWTO                  "Howto"
 
174
#define CFG_CAT_TERM_NONPROFIT              "Nonprofit"
 
175
#define CFG_CAT_TERM_TECH                   "Tech"
167
176
 
168
 
#define CFG_METHOD_FAVORITES                "favorites" 
169
 
#define CFG_METHOD_TAG                      "tag"
170
 
#define CFG_METHOD_USER                     "user"
171
 
#define CFG_METHOD_FEATURED                 "featured"
172
 
#define CFG_METHOD_PLAYLIST                 "playlist"
173
 
#define CFG_METHOD_POPULAR                  "popular"
174
 
#define CFG_METHOD_CATEGORY_AND_TAG         "category-and-tag"
 
177
#define CFG_REQUEST_STDFEED                 "standardfeed"
 
178
#define CFG_REQUEST_VIDEOSEARCH             "search"
 
179
#define CFG_REQUEST_FAVORITES               "favorites"
 
180
#define CFG_REQUEST_SUBSCRIPTIONS           "subscriptions"
 
181
#define CFG_REQUEST_PLAYLISTS               "playlists"
 
182
#define CFG_REQUEST_UPLOADS                 "uploads"
175
183
 
176
184
#define CFG_OPTION_USER                     "user"
177
185
#define CFG_OPTION_TAG                      "tag"
178
 
#define CFG_OPTION_STARTPAGE                "start-page"
 
186
#define CFG_OPTION_STARTINDEX               "start-index"
179
187
#define CFG_OPTION_AMOUNT                   "amount"
180
188
#define CFG_OPTION_PLAYLIST_ID              "id"
181
189
#define CFG_OPTION_PLAYLIST_NAME            "name"
182
190
#define CFG_OPTION_TIME_RANGE               "time-range"
183
 
#define CFG_OPTION_CATEGORY                 "category"
 
191
#define CFG_OPTION_AUTHOR                   "author"
 
192
 
 
193
#define CFG_OPTION_STDFEED                  "feed"
 
194
#define CFG_OPTION_REGION_ID                "region-id"
 
195
#define CFG_OPTION_SEARCH_QUERY             "query"
 
196
 
 
197
#define CFG_OPTION_REGION_AUSTRALIA         "au"
 
198
#define CFG_OPTION_REGION_BRAZIL            "br"
 
199
#define CFG_OPTION_REGION_CANADA            "ca"
 
200
#define CFG_OPTION_REGION_FRANCE            "fr"
 
201
#define CFG_OPTION_REGION_GERMANY           "de"
 
202
#define CFG_OPTION_REGION_GREAT_BRITAIN     "gb"
 
203
#define CFG_OPTION_REGION_HOLLAND           "nl"
 
204
#define CFG_OPTION_REGION_HONG_KONG         "hk"
 
205
#define CFG_OPTION_REGION_IRELAND           "ie"
 
206
#define CFG_OPTION_REGION_ITALY             "it"
 
207
#define CFG_OPTION_REGION_JAPAN             "jp"
 
208
#define CFG_OPTION_REGION_MEXICO            "mx"
 
209
#define CFG_OPTION_REGION_NEW_ZEALAND       "nz"
 
210
#define CFG_OPTION_REGION_POLAND            "pl"
 
211
#define CFG_OPTION_RUSSIA                   "ru"
 
212
#define CFG_OPTION_SOUTH_KOREA              "kr"
 
213
#define CFG_OPTION_SPAIN                    "es"
 
214
#define CFG_OPTION_TAIWAN                   "tw"
 
215
#define CFG_OPTION_UNITED_STATES            "us"
 
216
 
 
217
typedef struct regions regions;
 
218
struct regions
 
219
{
 
220
    yt_regions_t region;
 
221
    const char *region_code;
 
222
    const char *country;
 
223
};
 
224
 
 
225
static regions YT_regions[] = 
 
226
{    
 
227
    { YT_region_au, CFG_OPTION_REGION_AUSTRALIA,      "Australia"       },
 
228
    { YT_region_br, CFG_OPTION_REGION_BRAZIL,         "Brazil"          },
 
229
    { YT_region_ca, CFG_OPTION_REGION_CANADA,         "Canada"          },
 
230
    { YT_region_fr, CFG_OPTION_REGION_FRANCE,         "France"          },
 
231
    { YT_region_de, CFG_OPTION_REGION_GERMANY,        "Germany"         },
 
232
    { YT_region_gb, CFG_OPTION_REGION_GREAT_BRITAIN,  "Great Britain"   },
 
233
    { YT_region_nl, CFG_OPTION_REGION_HOLLAND,        "Netherlands"     },
 
234
    { YT_region_hk, CFG_OPTION_REGION_HONG_KONG,      "Hong Kong"       },
 
235
    { YT_region_ie, CFG_OPTION_REGION_IRELAND,        "Ireland"         },
 
236
    { YT_region_it, CFG_OPTION_REGION_ITALY,          "Italy"           },
 
237
    { YT_region_jp, CFG_OPTION_REGION_JAPAN,          "Japan"           },
 
238
    { YT_region_mx, CFG_OPTION_REGION_MEXICO,         "Mexico"          },
 
239
    { YT_region_nz, CFG_OPTION_REGION_NEW_ZEALAND,    "New Zealand"     },
 
240
    { YT_region_pl, CFG_OPTION_REGION_POLAND,         "Poland"          },
 
241
    { YT_region_ru, CFG_OPTION_RUSSIA,                "Russia"          },
 
242
    { YT_region_kr, CFG_OPTION_SOUTH_KOREA,           "South Korea"     },
 
243
    { YT_region_es, CFG_OPTION_SPAIN,                 "Spain"           },
 
244
    { YT_region_tw, CFG_OPTION_TAIWAN,                "Taiwan"          },
 
245
    { YT_region_us, CFG_OPTION_UNITED_STATES,         "United States"   },
 
246
    { YT_region_none, NULL , NULL },
 
247
};
184
248
 
185
249
YouTubeService::YouTubeService()
186
250
{
202
266
YouTubeService::YouTubeTask::YouTubeTask()
203
267
{
204
268
    parameters = zmm::Ref<Dictionary>(new Dictionary());
205
 
//    parameters->put(_(REST_PARAM_DEV_ID), ConfigManager::getInstance()->getOption(CFG_ONLINE_CONTENT_YOUTUBE_DEV_ID));
206
 
    method = YT_list_none;
207
 
    category = YT_cat_none;
 
269
    request = YT_request_none;
 
270
    region = YT_region_none;
208
271
    amount = 0;
209
272
    amount_fetched = 0;
210
 
    current_page = 0;
 
273
    start_index = 1;
 
274
    cfg_start_index = 1;
 
275
    subfeed_index = 0;
 
276
    kill = false;
211
277
}
212
278
 
213
 
 
214
279
service_type_t YouTubeService::getServiceType()
215
280
{
216
281
    return OS_YouTube;
221
286
    return _("YouTube");
222
287
}
223
288
 
224
 
String YouTubeService::getRequestName(yt_methods_t method)
 
289
String YouTubeService::getRequestName(yt_requests_t request)
225
290
{
226
291
    String temp;
227
292
 
228
 
    switch (method)
 
293
    switch (request)
229
294
    {
230
 
        case YT_list_favorite:
 
295
        case YT_request_stdfeed:
 
296
            temp = _(REQ_NAME_STDFEEDS);
 
297
            break;
 
298
        case YT_request_video_search:
 
299
            temp = _(REQ_NAME_VIDEO_SEARCH);
 
300
            break;
 
301
        case YT_request_user_favorites:
231
302
            temp = _(REQ_NAME_FAVORITES);
232
303
            break;
233
 
        case YT_list_featured:
234
 
            temp = _(REQ_NAME_FEATURED);
235
 
            break;
236
 
        case YT_list_popular:
237
 
            temp = _(REQ_NAME_POPULAR);
238
 
            break;
239
 
        case YT_list_by_playlist:
240
 
            temp = _(REQ_NAME_PLAYLIST);
241
 
            break;
242
 
        case YT_list_by_category_and_tag:
243
 
            temp = _(REQ_NAME_CATEGORY_AND_TAG);
244
 
            break;
245
 
        case YT_list_by_tag:
246
 
            temp = _(REQ_NAME_BY_TAG);
247
 
            break;
248
 
        case YT_list_by_user:
249
 
            temp = _(REQ_NAME_BY_USER);
250
 
            break;
251
 
        case YT_list_none:
 
304
        case YT_request_user_playlists:
 
305
        case YT_subrequest_playlists:
 
306
            temp = _(REQ_NAME_PLAYLISTS);
 
307
            break;
 
308
        case YT_request_user_subscriptions:
 
309
        case YT_subrequest_subscriptions:
 
310
            temp = _(REQ_NAME_SUBSCRIPTIONS);
 
311
            break;
 
312
        case YT_request_user_uploads:
 
313
            temp = _(REQ_NAME_UPLOADS);
 
314
            break;
 
315
        case YT_request_none:
252
316
        default:
253
317
            temp = nil;
254
318
            break;
257
321
    return temp;
258
322
}
259
323
 
260
 
String YouTubeService::getCategoryName(yt_categories_t category)
 
324
String YouTubeService::getRegionName(yt_regions_t region_code)
261
325
{
262
 
    String temp;
263
 
 
264
 
    switch (category)
265
 
    {
266
 
        case YT_cat_film_and_animation:
267
 
            temp = _(CAT_NAME_FILM_AND_ANIM);
268
 
            break;
269
 
        case YT_cat_autos_and_vehicles:
270
 
            temp = _(CAT_NAME_AUTOS_AND_VEHICLES);
271
 
            break;
272
 
        case YT_cat_music:
273
 
            temp = _(CAT_NAME_MUSIC);
274
 
            break;
275
 
        case YT_cat_pets_and_animals:
276
 
            temp = _(CAT_NAME_PETS_AND_ANIMALS);
277
 
            break;
278
 
        case YT_cat_sports:
279
 
            temp = _(CAT_NAME_SPORTS);
280
 
            break;
281
 
        case YT_cat_travel_and_places:
282
 
            temp = _(CAT_NAME_TRAVEL_AND_PLACES);
283
 
            break;
284
 
        case YT_cat_gadgets_and_games:
285
 
            temp = _(CAT_NAME_GADGETS_AND_GAMES);
286
 
            break;
287
 
        case YT_cat_people_and_blogs:
288
 
            temp = _(CAT_NAME_PEOPLE_AND_BLOGS);
289
 
            break;
290
 
        case YT_cat_comedy:
291
 
            temp = _(CAT_NAME_COMEDY);
292
 
            break;
293
 
        case YT_cat_entertainment:
294
 
            temp = _(CAT_NAME_ENTERTAINMENT);
295
 
            break;
296
 
        case YT_cat_news_and_politics:
297
 
            temp = _(CAT_NAME_NEWS_AND_POLITICS);
298
 
            break;
299
 
        case YT_cat_howto_and_diy:
300
 
            temp = _(CAT_NAME_HOWTO_AND_DIY);
301
 
            break;
302
 
        case YT_cat_none:
303
 
        default:
304
 
            temp = nil;
305
 
            break;
306
 
    }
307
 
 
308
 
    return temp;
 
326
    if ((region_code < 0) || (region_code >= YT_region_none))
 
327
        return nil;
 
328
    else
 
329
        return _(YT_regions[region_code].country);
309
330
}
310
331
 
311
 
 
 
332
#if 0
312
333
String YouTubeService::getCheckAttr(Ref<Element> xml, String attrname)
313
334
{
314
335
    String temp = xml->getAttribute(attrname);
316
337
        return temp;
317
338
    else
318
339
        throw _Exception(_("Tag <") + xml->getName() +
319
 
                         _("> is missing the requred \"") + attrname + 
320
 
                         _("\" attribute!"));
 
340
                _("> is missing the requred \"") + attrname + 
 
341
                _("\" attribute!"));
321
342
    return nil;
322
343
}
323
344
 
329
350
        itmp = temp.toInt();
330
351
    else
331
352
        throw _Exception(_("Tag <") + xml->getName() +
332
 
                         _("> is missing the requred \"") + attrname + 
333
 
                         _("\" attribute!"));
 
353
                _("> is missing the requred \"") + attrname + 
 
354
                _("\" attribute!"));
334
355
 
335
356
    if (itmp < 1)
336
357
        throw _Exception(_("Invalid value in ") + attrname + _(" for <") + 
337
 
                         xml->getName() + _("> tag"));
 
358
                xml->getName() + _("> tag"));
338
359
 
339
360
    return itmp;
340
361
}
341
362
 
342
 
void YouTubeService::addPagingParams(Ref<Element> xml, Ref<YouTubeTask> task)
 
363
#endif
 
364
 
 
365
void YouTubeService::getPagingParams(Ref<Element> xml, Ref<YouTubeTask> task)
343
366
{
344
367
    String temp;
345
368
    int itmp;
346
 
    temp = getCheckAttr(xml, _(CFG_OPTION_AMOUNT));
 
369
    temp = xml->getAttribute(_(CFG_OPTION_AMOUNT));
 
370
    if (!string_ok(temp))
 
371
        temp = _("all");
 
372
 
347
373
    if (temp == "all")
348
 
    {
349
374
        task->amount = AMOUNT_ALL;
350
 
        task->parameters->put(_(REST_PARAM_ITEMS_PER_PAGE),
351
 
                                    _(REST_VALUE_PER_PAGE_MAX));
352
 
    }
353
375
    else
354
376
    {
355
377
        itmp = getCheckPosIntAttr(xml, _(CFG_OPTION_AMOUNT));
356
 
        if (itmp >= _(REST_VALUE_PER_PAGE_MAX).toInt())
357
 
            task->parameters->put(_(REST_PARAM_ITEMS_PER_PAGE),
358
 
                    _(REST_VALUE_PER_PAGE_MAX));
359
 
        else
360
 
            task->parameters->put(_(REST_PARAM_ITEMS_PER_PAGE),
361
 
                    String::from(itmp));
 
378
        if (itmp > AMOUNT_ALL)
 
379
        {
 
380
            log_warning("Maximum amount of items to fetch can not exceed 1000\n");
 
381
            itmp = AMOUNT_ALL;
 
382
        }
362
383
        task->amount = itmp;
363
384
    }
364
385
 
365
 
    itmp = getCheckPosIntAttr(xml, _(CFG_OPTION_STARTPAGE));
366
 
    task->parameters->put(_(REST_PARAM_PAGE_NUMBER), 
367
 
            String::from(itmp));
368
 
}
369
 
 
370
 
 
371
 
Ref<Object> YouTubeService::defineServiceTask(Ref<Element> xmlopt)
 
386
    temp = xml->getAttribute(_(CFG_OPTION_STARTINDEX));
 
387
    if (!string_ok(temp))
 
388
        itmp = 1;
 
389
    else
 
390
    {
 
391
        itmp = getCheckPosIntAttr(xml, _(CFG_OPTION_STARTINDEX));
 
392
        if (itmp <= 0)
 
393
        {
 
394
            throw _Exception(_("Tag <") + xml->getName() + _("> ") + 
 
395
                    _(CFG_OPTION_STARTINDEX) + _(" must be at least 1!"));
 
396
        }
 
397
    }
 
398
    task->cfg_start_index = itmp;
 
399
    task->start_index = itmp;
 
400
}
 
401
 
 
402
void YouTubeService::addTimeParams(Ref<Element> xml, Ref<YouTubeTask> task)
 
403
{
 
404
    String temp;
 
405
    
 
406
    temp = xml->getAttribute(_(CFG_OPTION_TIME_RANGE));
 
407
    if (!string_ok(temp))
 
408
        return;
 
409
 
 
410
    if ((temp != GDATA_YT_VALUE_TIME_RANGE_ALL) &&
 
411
        (temp != GDATA_YT_VALUE_TIME_RANGE_DAY) &&
 
412
        (temp != GDATA_YT_VALUE_TIME_RANGE_WEEK) &&
 
413
        (temp != GDATA_YT_VALUE_TIME_RANGE_MONTH))
 
414
        throw _Exception(_("Invalid time range parameter \"") + temp + 
 
415
                _("\" in <") + xml->getName() + _("> tag"));
 
416
 
 
417
    task->parameters->put(_(GDATA_YT_PARAM_TIME), temp);
 
418
}
 
419
 
 
420
yt_regions_t YouTubeService::getRegion(Ref<Element> xml)
 
421
{
 
422
    String region = xml->getAttribute(_(CFG_OPTION_REGION_ID));
 
423
    if (!string_ok(region))
 
424
        return YT_region_none;
 
425
 
 
426
    int count = 0;
 
427
    while (YT_regions[count].region_code != NULL)
 
428
    {
 
429
        if (region == YT_regions[count].region_code)
 
430
            return YT_regions[count].region;
 
431
        count++;
 
432
    }
 
433
 
 
434
    throw _Exception(_("<") + xml->getName() + _("> tag has an invalid region setting: ") + region);
 
435
 
 
436
}
 
437
 
 
438
String YouTubeService::getFeed(Ref<Element> xml)
 
439
{
 
440
    String feed = xml->getAttribute(_(CFG_OPTION_STDFEED));
 
441
    if (!string_ok(feed))
 
442
        throw _Exception(_("<") + xml->getName() + _("> tag is missing the required feed setting!"));
 
443
 
 
444
    int count = 0;
 
445
    while (YT_stdfeeds[count] != NULL)
 
446
    {
 
447
        if (feed == YT_stdfeeds[count])
 
448
            return feed;
 
449
        count++;
 
450
    }
 
451
 
 
452
    throw _Exception(_("<") + xml->getName() + _("> tag has an invalid feed setting: ") + feed);
 
453
 
 
454
}
 
455
Ref<Object> YouTubeService::defineServiceTask(Ref<Element> xmlopt, Ref<Object> params)
372
456
{
373
457
    Ref<YouTubeTask> task(new YouTubeTask());
374
458
    String temp = xmlopt->getName();
 
459
    String temp2;
 
460
    Ref<Option> racy = RefCast(params, Option);
375
461
    
376
 
    if (temp == CFG_METHOD_FAVORITES)
377
 
        task->method = YT_list_favorite;
378
 
    else if (temp == CFG_METHOD_TAG)
379
 
        task->method = YT_list_by_tag;
380
 
    else if (temp == CFG_METHOD_USER)
381
 
        task->method = YT_list_by_user;
382
 
    else if (temp == CFG_METHOD_FEATURED)
383
 
        task->method = YT_list_featured;
384
 
    else if (temp == CFG_METHOD_PLAYLIST)
385
 
        task->method = YT_list_by_playlist;
386
 
    else if (temp == CFG_METHOD_POPULAR)
387
 
        task->method = YT_list_popular;
388
 
    else if (temp == CFG_METHOD_CATEGORY_AND_TAG)
389
 
        task->method = YT_list_by_category_and_tag;
 
462
    if (temp == CFG_REQUEST_STDFEED)
 
463
        task->request = YT_request_stdfeed;
 
464
    else if (temp == CFG_REQUEST_VIDEOSEARCH)
 
465
        task->request = YT_request_video_search;
 
466
    else if (temp == CFG_REQUEST_FAVORITES)
 
467
        task->request = YT_request_user_favorites;
 
468
    else if (temp == CFG_REQUEST_SUBSCRIPTIONS)
 
469
        task->request = YT_request_user_subscriptions;
 
470
    else if (temp == CFG_REQUEST_PLAYLISTS)
 
471
        task->request = YT_request_user_playlists;
 
472
    else if (temp == CFG_REQUEST_UPLOADS)
 
473
        task->request = YT_request_user_uploads;
390
474
    else throw _Exception(_("Unsupported tag while parsing YouTube options: ") + temp);
391
475
 
392
 
    if (!hasPaging(task->method))
393
 
        task->amount = AMOUNT_ALL;
 
476
    task->amount = AMOUNT_ALL;
394
477
 
395
 
    switch (task->method)
 
478
    task->parameters->put(_(GDATA_PARAM_FEED_FORMAT), 
 
479
                          _(GDATA_VALUE_FEED_FORMAT_RSS));
 
480
    switch (task->request)
396
481
    {
397
 
        case YT_list_favorite:
398
 
            task->parameters->put(_(REST_PARAM_METHOD),
399
 
                                  _(REST_METHOD_LIST_FAVORITE));
400
 
 
401
 
            task->parameters->put(_(REST_PARAM_USER), 
402
 
                                  getCheckAttr(xmlopt, _(CFG_OPTION_USER)));
403
 
            break;
404
 
 
405
 
        case YT_list_by_tag:
406
 
            task->parameters->put(_(REST_PARAM_METHOD),
407
 
                                  _(REST_METHOD_LIST_BY_TAG));
408
 
 
409
 
            task->parameters->put(_(REST_PARAM_TAG), 
410
 
                                  getCheckAttr(xmlopt, _(CFG_OPTION_TAG)));
411
 
 
412
 
            addPagingParams(xmlopt, task);
413
 
            break;
414
 
 
415
 
        case YT_list_by_user:
416
 
            task->parameters->put(_(REST_PARAM_METHOD),
417
 
                                  _(REST_METHOD_LIST_BY_USER));
418
 
 
419
 
            task->parameters->put(_(REST_PARAM_USER), 
420
 
                                  getCheckAttr(xmlopt, _(CFG_OPTION_USER)));
421
 
 
422
 
            addPagingParams(xmlopt, task);
423
 
            break;
424
 
 
425
 
        case YT_list_featured:
426
 
            task->parameters->put(_(REST_PARAM_METHOD),
427
 
                                  _(REST_METHOD_LIST_FEATURED));
428
 
            break;
429
 
 
430
 
        case YT_list_by_playlist:
431
 
            task->parameters->put(_(REST_PARAM_METHOD),
432
 
                                  _(REST_METHOD_LIST_BY_PLAYLIST));
433
 
            task->parameters->put(_(REST_PARAM_PLAYLIST_ID),
434
 
                               getCheckAttr(xmlopt, _(CFG_OPTION_PLAYLIST_ID)));
435
 
            addPagingParams(xmlopt, task); 
436
 
          
437
 
            task->playlist_name = 
438
 
                getCheckAttr(xmlopt, _(CFG_OPTION_PLAYLIST_NAME));
439
 
 
440
 
            break;
441
 
        case YT_list_popular:
442
 
            task->parameters->put(_(REST_PARAM_METHOD),
443
 
                                  _(REST_METHOD_LIST_POPULAR));
444
 
            temp = getCheckAttr(xmlopt, _(CFG_OPTION_TIME_RANGE));
445
 
            if ((temp != REST_VALUE_TIME_RANGE_ALL) &&
446
 
                (temp != REST_VALUE_TIME_RANGE_DAY) &&
447
 
                (temp != REST_VALUE_TIME_RANGE_WEEK) &&
448
 
                (temp != REST_VALUE_TIME_RANGE_MONTH))
449
 
            {
450
 
                throw _Exception(_("Invalid time range specified for <") +
451
 
                                 xmlopt->getName() + _("< tag!"));
452
 
            }
453
 
            else 
454
 
                task->parameters->put(_(REST_PARAM_TIME_RANGE), temp);
455
 
            break;
456
 
 
457
 
        case YT_list_by_category_and_tag:
458
 
            task->parameters->put(_(REST_PARAM_METHOD),
459
 
                                  _(REST_METHOD_LIST_BY_CAT_AND_TAG));
460
 
            task->parameters->put(_(REST_PARAM_TAG),
461
 
                                  getCheckAttr(xmlopt, _(CFG_OPTION_TAG)));
 
482
        case YT_request_stdfeed:
 
483
            task->parameters->put(_(GDATA_YT_PARAM_FORMAT),
 
484
                                  _(GDATA_YT_VALUE_FORMAT_SWF));
 
485
 
 
486
            temp2 = getFeed(xmlopt);
 
487
            task->url_part = _(GDATA_REQUEST_STDFEED_BASE) + _("/");
 
488
 
 
489
            if (temp2 != GDATA_REQUEST_STDFEED_WATCH_ON_MOBILE)
 
490
            {
 
491
                yt_regions_t r = getRegion(xmlopt);
 
492
                if (r < YT_region_none)
 
493
                {
 
494
                    task->url_part = task->url_part + 
 
495
                          YT_regions[r].region_code + _("/");
 
496
                    task->region = r;
 
497
                }
 
498
            }
 
499
 
 
500
            task->url_part = task->url_part + temp2;
 
501
            if ((temp2 != GDATA_REQUEST_STDFEED_MOST_RECENT) &&
 
502
                (temp2 != GDATA_REQUEST_STDFEED_RECENTLY_FEATURED) &&
 
503
                (temp2 != GDATA_REQUEST_STDFEED_WATCH_ON_MOBILE))
 
504
            {
 
505
                addTimeParams(xmlopt, task);
 
506
            }
 
507
 
 
508
            task->parameters->put(_(GDATA_YT_PARAM_RESTRICTED_CONTENT),
 
509
                                  racy->getOption());
 
510
 
 
511
            getPagingParams(xmlopt, task);
 
512
 
 
513
            break;
 
514
 
 
515
        case YT_request_video_search:
 
516
            task->parameters->put(_(GDATA_YT_PARAM_FORMAT),
 
517
                                  _(GDATA_YT_VALUE_FORMAT_SWF));
 
518
            task->url_part = _(GDATA_REQUEST_SEARCH);
 
519
            /// \todo  check if this needs additional URL escaping
 
520
            temp = getCheckAttr(xmlopt, _(CFG_OPTION_SEARCH_QUERY));
 
521
            task->parameters->put(_(GDATA_YT_PARAM_VIDEO_QUERY), temp);
 
522
            
 
523
            temp = xmlopt->getAttribute(_(CFG_OPTION_AUTHOR));
 
524
            if (string_ok(temp))
 
525
                task->parameters->put(_(GDATA_YT_PARAM_AUTHOR), temp);
462
526
           
463
 
            temp = getCheckAttr(xmlopt, _(CFG_OPTION_CATEGORY));
464
 
            if (temp == CFG_CAT_STRING_FILM_AND_ANIM)
465
 
            {
466
 
                task->category = YT_cat_film_and_animation;
467
 
                temp = String::from(YT_cat_film_and_animation);
468
 
            }
469
 
            else if (temp == CFG_CAT_STRING_AUTOS_AND_VEHICLES)
470
 
            {
471
 
                task->category = YT_cat_autos_and_vehicles;
472
 
                temp = String::from(YT_cat_autos_and_vehicles);
473
 
            }
474
 
            else if (temp == CFG_CAT_STRING_COMEDY)
475
 
            {
476
 
                task->category = YT_cat_comedy;
477
 
                temp = String::from(YT_cat_comedy);
478
 
            }
479
 
            else if (temp == CFG_CAT_STRING_ENTERTAINMENT)
480
 
            {
481
 
                task->category = YT_cat_entertainment;
482
 
                temp = String::from(YT_cat_entertainment);
483
 
            }
484
 
            else if (temp == CFG_CAT_STRING_MUSIC)
485
 
            {
486
 
                task->category = YT_cat_music;
487
 
                temp = String::from(YT_cat_music);
488
 
            }
489
 
            else if (temp == CFG_CAT_STRING_NEWS_AND_POLITICS)
490
 
            {
491
 
                task->category = YT_cat_news_and_politics;
492
 
                temp = String::from(YT_cat_news_and_politics);
493
 
            }
494
 
            else if (temp == CFG_CAT_STRING_PEOPLE_AND_BLOGS)
495
 
            {
496
 
                task->category = YT_cat_people_and_blogs;
497
 
                temp = String::from(YT_cat_people_and_blogs);
498
 
            }
499
 
            else if (temp == CFG_CAT_STRING_PETS_AND_ANIMALS)
500
 
            {
501
 
                task->category = YT_cat_pets_and_animals;
502
 
                temp = String::from(YT_cat_pets_and_animals);
503
 
            }
504
 
            else if (temp == CFG_CAT_STRING_HOWTO_AND_DIY)
505
 
            {
506
 
                task->category = YT_cat_howto_and_diy;
507
 
                temp = String::from(YT_cat_howto_and_diy);
508
 
            }
509
 
            else if (temp == CFG_CAT_STRING_SPORTS)
510
 
            {
511
 
                task->category = YT_cat_sports;
512
 
                temp = String::from(YT_cat_sports);
513
 
            }
514
 
            else if (temp == CFG_CAT_STRING_TRAVEL_AND_PLACES)
515
 
            {
516
 
                task->category = YT_cat_travel_and_places;
517
 
                temp = String::from(YT_cat_travel_and_places);
518
 
            }
519
 
            else if (temp == CFG_CAT_STRING_GADGETS_AND_GAMES)
520
 
            {
521
 
                task->category = YT_cat_gadgets_and_games;
522
 
                temp = String::from(YT_cat_gadgets_and_games);
523
 
            }
524
 
            else
525
 
            {
526
 
                throw _Exception(_("Invalid category specified for <") +
527
 
                        xmlopt->getName() + _("< tag!"));
528
 
            }
529
 
            task->parameters->put(_(REST_PARAM_CATEGORY_ID), temp);
530
 
 
531
 
            addPagingParams(xmlopt, task);
532
 
            break;
533
 
 
534
 
        case YT_list_none:
 
527
            task->parameters->put(_(GDATA_YT_PARAM_RESTRICTED_CONTENT),
 
528
                                  racy->getOption());
 
529
 
 
530
 
 
531
            getPagingParams(xmlopt, task);
 
532
 
 
533
            break;
 
534
        case YT_request_user_favorites:
 
535
            task->parameters->put(_(GDATA_YT_PARAM_FORMAT),
 
536
                                  _(GDATA_YT_VALUE_FORMAT_SWF));
 
537
            temp = getCheckAttr(xmlopt, _(CFG_OPTION_USER));
 
538
            task->url_part = _(GDATA_REQUEST_USERS) + temp + 
 
539
                             _(GDATA_REQUEST_FAVORITES);
 
540
     
 
541
            task->parameters->put(_(GDATA_YT_PARAM_RESTRICTED_CONTENT),
 
542
                                  racy->getOption());
 
543
 
 
544
            getPagingParams(xmlopt, task);
 
545
            break;
 
546
        case YT_request_user_subscriptions:
 
547
            temp = getCheckAttr(xmlopt, _(CFG_OPTION_USER));
 
548
            task->url_part = _(GDATA_REQUEST_USERS) + temp +
 
549
                             _(GDATA_REQUEST_SUBSCRIPTIONS);
 
550
            task->amount = AMOUNT_ALL;
 
551
            break;
 
552
        case YT_request_user_playlists:
 
553
            temp = getCheckAttr(xmlopt, _(CFG_OPTION_USER));
 
554
            task->url_part = _(GDATA_REQUEST_USERS) + temp +
 
555
                             _(GDATA_REQUEST_PLAYLISTS);
 
556
            task->amount = AMOUNT_ALL;
 
557
            break;
 
558
        case YT_request_user_uploads:
 
559
            task->parameters->put(_(GDATA_YT_PARAM_FORMAT),
 
560
                                  _(GDATA_YT_VALUE_FORMAT_SWF));
 
561
            temp = getCheckAttr(xmlopt, _(CFG_OPTION_USER));
 
562
            task->url_part = _(GDATA_REQUEST_USERS) + temp + 
 
563
                             _(GDATA_REQUEST_UPLOADS);
 
564
     
 
565
            task->parameters->put(_(GDATA_YT_PARAM_RESTRICTED_CONTENT),
 
566
                                  racy->getOption());
 
567
 
 
568
            getPagingParams(xmlopt, task);
 
569
            break;
 
570
        case YT_request_none:
535
571
        default:
536
572
            throw _Exception(_("Unsupported tag!"));
537
573
            break;
539
575
    return RefCast(task, Object);
540
576
}
541
577
 
542
 
Ref<Element> YouTubeService::getData(Ref<Dictionary> params)
 
578
Ref<Element> YouTubeService::getData(String url_part, Ref<Dictionary> params, bool construct_url)
543
579
{
544
580
    long retcode;
 
581
    String URL;
545
582
    Ref<StringConverter> sc = StringConverter::i2i();
546
583
 
547
 
    // dev id is requied in each call
548
 
    String URL = _(REST_BASE_URL) + params->encode();
 
584
    if (construct_url)
 
585
        URL = _(GDATA_API_YT_BASE_URL) + url_part;
 
586
    else
 
587
        URL = url_part;
 
588
    
 
589
    if ((params != nil) && (params->size() > 0))
 
590
    {
 
591
        if (URL.index('?') > 0)
 
592
            URL = URL + _("&") + params->encode();
 
593
        else
 
594
            URL = URL + _("?") + params->encode();
 
595
    }
549
596
 
550
597
    log_debug("Retrieving URL: %s\n", URL.c_str());
551
598
   
552
599
    Ref<StringBuffer> buffer;
553
600
    try 
554
601
    {
555
 
        log_debug("DOWNLOADING URL: %s\n", URL.c_str());
556
602
        buffer = url->download(URL, &retcode, curl_handle, false, true);
557
603
    }
558
604
    catch (Exception ex)
568
614
    if (retcode != 200)
569
615
        return nil;
570
616
 
571
 
    log_debug("GOT BUFFER\n%s\n", buffer->toString().c_str()); 
 
617
//    log_debug("GOT BUFFER\n%s\n", buffer->toString().c_str()); 
572
618
    Ref<Parser> parser(new Parser());
573
619
    try
574
620
    {
591
637
    return nil;
592
638
}
593
639
 
594
 
bool YouTubeService::hasPaging(yt_methods_t method)
 
640
void YouTubeService::killOneTimeTasks(Ref<Array<Object> > tasklist)
595
641
{
596
 
    switch (method)
597
 
    {
598
 
        case YT_list_by_tag:
599
 
        case YT_list_by_user:
600
 
        case YT_list_by_playlist:
601
 
        case YT_list_by_category_and_tag:
602
 
            return true;
603
 
 
604
 
        case YT_list_popular:
605
 
        case YT_list_featured:
606
 
        case YT_list_none:
607
 
        case YT_list_favorite:
608
 
        default:
609
 
            return false;
610
 
    }
611
 
    return false;
 
642
    int current = 0;
 
643
 
 
644
    for (int i = 0; i < tasklist->size(); i++)
 
645
    {
 
646
        Ref<YouTubeTask> task = RefCast(tasklist->get(i), YouTubeTask);
 
647
    }
 
648
    while (true)
 
649
    {
 
650
        Ref<YouTubeTask> task = RefCast(tasklist->get(current), YouTubeTask);
 
651
        if ((task != nil) && (task->kill))
 
652
            tasklist->removeUnordered(current);
 
653
        else
 
654
            current++;
 
655
 
 
656
        if (current >= tasklist->size())
 
657
            break;
 
658
    }
 
659
    for (int i = 0; i < tasklist->size(); i++)
 
660
    {
 
661
        Ref<YouTubeTask> task = RefCast(tasklist->get(i), YouTubeTask);
 
662
    }
612
663
}
613
664
 
614
665
bool YouTubeService::refreshServiceData(Ref<Layout> layout)
637
688
    if (task == nil)
638
689
        throw _Exception(_("Encountered invalid task!"));
639
690
 
640
 
    task->parameters->put(_(REST_PARAM_DEV_ID), ConfigManager::getInstance()->getOption(CFG_ONLINE_CONTENT_YOUTUBE_DEV_ID));
641
 
 
642
 
    if (hasPaging(task->method) && 
643
 
       ((task->amount == AMOUNT_ALL) || (task->amount > PER_PAGE_MAX)))
 
691
    if (task->amount_fetched < task->amount)
644
692
    {
645
 
        task->current_page++;
646
 
        task->parameters->put(_(REST_PARAM_PAGE_NUMBER),
647
 
                              String::from(task->current_page));
 
693
        // yt start index begins at 1
 
694
        task->start_index = task->cfg_start_index + task->amount_fetched;
 
695
        task->parameters->put(_(GDATA_YT_PARAM_START_INDEX),
 
696
                              String::from(task->start_index));
 
697
 
 
698
        if ((task->amount - task->amount_fetched) >=
 
699
             _(GDATA_YT_VALUE_PER_PAGE_MAX).toInt())
 
700
        {
 
701
           task->parameters->put(_(GDATA_YT_PARAM_MAX_RESULTS_PER_REQ),
 
702
                                 _(GDATA_YT_VALUE_PER_PAGE_MAX));
 
703
        }
 
704
        else if ((task->amount - task->amount_fetched) < 
 
705
                _(GDATA_YT_VALUE_PER_PAGE_MAX).toInt())
 
706
        {
 
707
            task->parameters->put(_(GDATA_YT_PARAM_MAX_RESULTS_PER_REQ),
 
708
                    String::from(task->amount - task->amount_fetched));
 
709
        }
648
710
    }
649
711
 
650
 
    Ref<Element> reply = getData(task->parameters);
651
 
 
 
712
 
 
713
    bool b = false;
 
714
    bool construct_url = true;
 
715
 
 
716
    Ref<Element> reply;
652
717
    Ref<YouTubeContentHandler> yt(new YouTubeContentHandler());
653
 
    bool b = false;
 
718
 
 
719
    if ((task->request == YT_request_user_subscriptions) ||
 
720
        (task->request == YT_request_user_playlists)) 
 
721
    {
 
722
       reply = getData(task->url_part, task->parameters, true);
 
723
       if (reply == nil)
 
724
           throw _Exception(_("Failed to retrieve YouTube subfeed"));
 
725
 
 
726
       task->subfeed = yt->getSubFeed(reply);
 
727
 
 
728
        // create new tasks
 
729
        for (int f = 0; f < task->subfeed->links->size(); f++)
 
730
        {
 
731
            Ref<YouTubeTask> subtask(new YouTubeTask());
 
732
            subtask->kill = true; // autoremove after one time execution
 
733
            if (task->request == YT_request_user_subscriptions)
 
734
                subtask->request = YT_subrequest_subscriptions;
 
735
            else if (task->request == YT_request_user_playlists)
 
736
                subtask->request = YT_subrequest_playlists;
 
737
            else
 
738
                subtask->request = YT_request_none;
 
739
 
 
740
            subtask->url_part = task->subfeed->links->get(f);
 
741
            subtask->amount = AMOUNT_ALL;
 
742
            subtask->sub_request_name = task->subfeed->title;
 
743
            subtask->parameters->put(_(GDATA_YT_PARAM_FORMAT),
 
744
                                     _(GDATA_YT_VALUE_FORMAT_SWF));
 
745
            subtask->parameters->put(_(GDATA_PARAM_FEED_FORMAT),
 
746
                                     _(GDATA_VALUE_FEED_FORMAT_RSS));
 
747
 
 
748
            tasklist->append(RefCast(subtask, Object));
 
749
        }
 
750
 
 
751
        current_task++;
 
752
        if (current_task >= tasklist->size())
 
753
        {
 
754
            current_task = 0;
 
755
            killOneTimeTasks(tasklist);
 
756
            return false;
 
757
        }
 
758
        return true;
 
759
    }
 
760
 
 
761
    if ((task->request == YT_subrequest_subscriptions) ||
 
762
       (task->request == YT_subrequest_playlists))
 
763
        construct_url = false;
 
764
 
 
765
    reply = getData(task->url_part, task->parameters, construct_url);
 
766
 
654
767
    if (reply != nil)
655
768
        b = yt->setServiceContent(reply);
656
769
    else
663
776
    if (!b)
664
777
    {
665
778
        log_debug("End of pages\n");
666
 
        if (hasPaging(task->method))
667
 
        {
668
 
            task->current_page = 0;
669
 
            task->amount_fetched = 0;
670
 
        }
 
779
        task->start_index = task->cfg_start_index;
 
780
        task->amount_fetched = 0;
 
781
        
671
782
        current_task++;
672
783
        if (current_task >= tasklist->size())
673
784
        {
674
785
            current_task = 0;
 
786
            killOneTimeTasks(tasklist);
675
787
            return false;
676
788
        }
677
789
   
697
809
        {
698
810
            log_debug("Adding new YouTube object\n");
699
811
            obj->setAuxData(_(YOUTUBE_AUXDATA_REQUEST), 
700
 
                            String::from(task->method));
 
812
                            String::from(task->request));
701
813
 
702
 
            if (task->method == YT_list_by_category_and_tag)
703
 
            {
704
 
                obj->setAuxData(_(YOUTUBE_AUXDATA_REQUEST_SUBNAME),
705
 
                        String::from(task->category));
706
 
            }
707
 
            else if (task->method == YT_list_by_user)
708
 
            {
709
 
                obj->setAuxData(_(YOUTUBE_AUXDATA_REQUEST_SUBNAME), 
710
 
                        task->parameters->get(_(REST_PARAM_USER)));
711
 
            }
712
 
            else if (task->method == YT_list_favorite)
713
 
            {
714
 
                obj->setAuxData(_(YOUTUBE_AUXDATA_REQUEST_SUBNAME),
715
 
                        task->parameters->get(_(REST_PARAM_USER)));
716
 
            }
717
 
            else if (task->method == YT_list_by_playlist)
718
 
            {
719
 
                obj->setAuxData(_(YOUTUBE_AUXDATA_REQUEST_SUBNAME), 
720
 
                        task->playlist_name);
721
 
            }
722
 
            else if (task->method == YT_list_by_tag)
723
 
            {
724
 
                obj->setAuxData(_(YOUTUBE_AUXDATA_REQUEST_SUBNAME),
725
 
                        task->parameters->get(_(REST_PARAM_TAG)));
 
814
            if ((task->request == YT_subrequest_playlists) ||
 
815
                (task->request == YT_subrequest_subscriptions))
 
816
            {
 
817
                obj->setAuxData(_(YOUTUBE_AUXDATA_SUBREQUEST_NAME),
 
818
                        task->sub_request_name);
 
819
            } 
 
820
            else if (task->request == YT_request_stdfeed)
 
821
            {
 
822
                if (task->region != YT_region_none)
 
823
                     obj->setAuxData(_(YOUTUBE_AUXDATA_REGION), 
 
824
                         String::from((int)task->region));
726
825
            }
727
826
            
728
827
            if (layout != nil)
729
828
                layout->processCdsObject(obj);
 
829
            else
 
830
            {
 
831
                log_warning("Your virtual layout is disabled, YouTube objects will not be added\n");
 
832
            }
730
833
        }
731
834
        else
732
835
        {
741
844
            ContentManager::getInstance()->updateObject(obj);
742
845
        }
743
846
 
744
 
        if (task->amount != AMOUNT_ALL)
 
847
        task->amount_fetched++;
 
848
        // max amount reached, reset paging and break to next task
 
849
        if (task->amount_fetched >= task->amount)
745
850
        {
746
 
            task->amount_fetched++;
747
 
            // max amount reached, reset paging and break to next task
748
 
            if (task->amount_fetched >= task->amount)
 
851
            task->amount_fetched = 0;
 
852
            task->start_index = task->cfg_start_index;
 
853
            
 
854
            current_task++;
 
855
            if (current_task >= tasklist->size())
749
856
            {
750
 
                task->amount_fetched = 0;
751
 
                if (hasPaging(task->method))
752
 
                {
753
 
                    task->current_page = 0;
754
 
                }
755
 
                current_task++;
756
 
                if (current_task >= tasklist->size())
757
 
                {
758
 
                    current_task = 0;
759
 
                    return false;
760
 
                }
 
857
                current_task = 0;
 
858
                killOneTimeTasks(tasklist);
 
859
                return false;
761
860
            }
762
861
        }
763
862
 
767
866
    }
768
867
    while (obj != nil);
769
868
 
770
 
    if (!hasPaging(task->method))
 
869
    current_task++;
 
870
    if (current_task >= tasklist->size())
771
871
    {
772
 
        current_task++;
773
 
        if (current_task >= tasklist->size())
774
 
        {
775
 
            current_task = 0;
776
 
            return false;
777
 
        }
 
872
        current_task = 0;
 
873
        killOneTimeTasks(tasklist);
 
874
        return false;
778
875
    }
779
876
 
780
877
    return true;