1 /*
2  * Created by Paul Gardner
3  * Created on Nov 25, 2008
4  *
5  * Copyright (C) Azureus Software, Inc, All Rights Reserved.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  */
19 
20 
21 package com.aelitis.azureus.core.cnetwork.impl;
22 
23 import java.io.IOException;
24 import java.util.*;
25 
26 import org.gudy.azureus2.core3.config.COConfigurationManager;
27 import org.gudy.azureus2.core3.config.ParameterListener;
28 import org.gudy.azureus2.core3.internat.MessageText;
29 import org.gudy.azureus2.core3.util.Base32;
30 import org.gudy.azureus2.core3.util.Constants;
31 import org.gudy.azureus2.core3.util.SystemTime;
32 import org.gudy.azureus2.core3.util.UrlUtils;
33 import org.gudy.azureus2.plugins.utils.FeatureManager;
34 import org.gudy.azureus2.plugins.utils.FeatureManager.FeatureDetails;
35 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
36 
37 import com.aelitis.azureus.core.crypto.VuzeCryptoManager;
38 import com.aelitis.azureus.core.metasearch.MetaSearchManagerFactory;
39 import com.aelitis.azureus.util.ImportExportUtils;
40 
41 public class
42 ContentNetworkVuzeGeneric
43 	extends ContentNetworkImpl
44 {
45 	private static String URL_SUFFIX;
46 
47 	static {
COConfigurationManager.addAndFireParameterListeners(new String[] { R, R }, new ParameterListener() { public void parameterChanged(String parameterName) { boolean send_info = COConfigurationManager.getBooleanParameter(R); URL_SUFFIX = R + (send_info ? Base32.encode(VuzeCryptoManager.getSingleton().getPlatformAZID()) : R) + R + Constants.AZUREUS_VERSION + R + MessageText.getCurrentLocale().toString() + R + UrlUtils.encode(System.getProperty(R)) + R; String suffix = System.getProperty(R, null); if (suffix != null) { URL_SUFFIX += R + suffix; } } })48 		COConfigurationManager.addAndFireParameterListeners(new String[] {
49 			"Send Version Info",
50 			"locale"
51 		}, new ParameterListener() {
52 			public void parameterChanged(String parameterName) {
53 				// Don't change the order of the params as there's some code somewhere
54 				// that depends on them (I think its code that removes the azid so
55 				// we can fix this up when that code's migrated here I guess
56 				boolean send_info = COConfigurationManager.getBooleanParameter("Send Version Info");
57 
58 				URL_SUFFIX = "azid="
59 						+ (send_info
60 								? Base32.encode(VuzeCryptoManager.getSingleton().getPlatformAZID())
61 								: "anonymous") + "&azv=" + Constants.AZUREUS_VERSION
62 						+ "&locale=" + MessageText.getCurrentLocale().toString() + "&os.name="
63 						+ UrlUtils.encode(System.getProperty("os.name")) + "&vzemb=1";
64 				String suffix = System.getProperty("url.suffix", null);
65 				if (suffix != null) {
66 					URL_SUFFIX += "&" + suffix;
67 				}
68 			}
69 		});
70 	}
71 
72 	private static final String RPC_ADDRESS = System.getProperty("platform_rpc",
73 			"https://vrpc.vuze.com/vzrpc/rpc.php");
74 
75 	private Map<Integer, String>		service_map = new HashMap<Integer, String>();
76 
77 	private Set<Integer>				service_exclusions;
78 
79 	private String	SITE_HOST;
80 	private String	URL_PREFIX;
81 	private String	URL_EXT_PREFIX;
82 	private String	URL_ICON;
83 	private String	URL_RELAY_RPC;
84 	private String	URL_AUTHORIZED_RPC;
85 	private String	URL_FAQ;
86 	private String	URL_BLOG;
87 	private String	URL_FORUMS;
88 	private String	URL_WIKI;
89 
90 
91 	public
ContentNetworkVuzeGeneric( ContentNetworkManagerImpl _manager, long _content_network, long _version, String _name, Map<String,Object> _pprop_defaults, Set<Integer> _service_exclusions, String _site_host, String _url_prefix, String _url_icon, String _url_relay_rpc, String _url_authorised_rpc, String _url_faq, String _url_blog, String _url_forums, String _url_wiki, String _url_ext_prefix )92 	ContentNetworkVuzeGeneric(
93 		ContentNetworkManagerImpl	_manager,
94 		long						_content_network,
95 		long						_version,
96 		String						_name,
97 		Map<String,Object>			_pprop_defaults,
98 		Set<Integer>				_service_exclusions,
99 		String						_site_host,
100 		String						_url_prefix,
101 		String						_url_icon,
102 		String						_url_relay_rpc,
103 		String						_url_authorised_rpc,
104 		String						_url_faq,
105 		String						_url_blog,
106 		String						_url_forums,
107 		String						_url_wiki,
108 		String						_url_ext_prefix )
109 	{
110 		super( _manager, TYPE_VUZE_GENERIC, _content_network, _version, _name, _pprop_defaults );
111 
112 		SITE_HOST				= _site_host;
113 		URL_PREFIX 				= _url_prefix;
114 		URL_ICON				= _url_icon;
115 		URL_RELAY_RPC			= _url_relay_rpc;
116 		URL_AUTHORIZED_RPC		= _url_authorised_rpc;
117 		URL_FAQ					= _url_faq;
118 		URL_BLOG				= _url_blog;
119 		URL_FORUMS				= _url_forums;
120 		URL_WIKI				= _url_wiki;
121 		URL_EXT_PREFIX = _url_ext_prefix;
122 
123 		service_exclusions		= _service_exclusions;
124 
125 		init();
126 	}
127 
128 	protected
ContentNetworkVuzeGeneric( ContentNetworkManagerImpl _manager, Map<String,Object> _map )129 	ContentNetworkVuzeGeneric(
130 		ContentNetworkManagerImpl	_manager,
131 		Map<String,Object>			_map )
132 
133 		throws IOException
134 	{
135 		super( _manager );
136 
137 		importFromBEncodedMap( _map );
138 	}
139 
140 	protected void
importFromBEncodedMap( Map<String,Object> map )141 	importFromBEncodedMap(
142 		Map<String,Object>			map )
143 
144 		throws IOException
145 	{
146 		super.importFromBEncodedMap( map );
147 
148 		SITE_HOST				= ImportExportUtils.importString(map, "vg_site" );
149 		URL_PREFIX 				= ImportExportUtils.importString(map, "vg_prefix" );
150 		URL_EXT_PREFIX 				= ImportExportUtils.importString(map, "vg_ext_prefix" );
151 		if (URL_EXT_PREFIX == null) {
152 			URL_EXT_PREFIX = URL_PREFIX;
153 		}
154 		URL_ICON 				= ImportExportUtils.importString(map, "vg_icon" );
155 		URL_RELAY_RPC			= ImportExportUtils.importString(map, "vg_relay_rpc" );
156 		URL_AUTHORIZED_RPC		= ImportExportUtils.importString(map, "vg_auth_rpc" );
157 		URL_FAQ					= ImportExportUtils.importString(map, "vg_faq" );
158 		URL_BLOG				= ImportExportUtils.importString(map, "vg_blog" );
159 		URL_FORUMS				= ImportExportUtils.importString(map, "vg_forums" );
160 		URL_WIKI				= ImportExportUtils.importString(map, "vg_wiki" );
161 
162 		List<Long>	sex = (List<Long>)map.get( "vg_sex" );
163 
164 		if ( sex != null ){
165 
166 			service_exclusions = new HashSet<Integer>();
167 
168 			for ( Long l: sex ){
169 
170 				service_exclusions.add( l.intValue());
171 			}
172 		}
173 
174 		init();
175 	}
176 
177 	protected void
exportToBEncodedMap( Map map )178 	exportToBEncodedMap(
179 		Map			map )
180 
181 		throws IOException
182 	{
183 		super.exportToBEncodedMap( map );
184 
185 		ImportExportUtils.exportString(map, "vg_site", 		SITE_HOST );
186 		ImportExportUtils.exportString(map, "vg_prefix", 	URL_PREFIX );
187 		ImportExportUtils.exportString(map, "vg_ext_prefix", 	URL_EXT_PREFIX );
188 		ImportExportUtils.exportString(map, "vg_icon", 		URL_ICON );
189 		ImportExportUtils.exportString(map, "vg_relay_rpc", URL_RELAY_RPC );
190 		ImportExportUtils.exportString(map, "vg_auth_rpc", 	URL_AUTHORIZED_RPC );
191 		ImportExportUtils.exportString(map, "vg_faq", 		URL_FAQ );
192 		ImportExportUtils.exportString(map, "vg_blog", 		URL_BLOG );
193 		ImportExportUtils.exportString(map, "vg_forums",	URL_FORUMS );
194 		ImportExportUtils.exportString(map, "vg_wiki",		URL_WIKI );
195 
196 		if ( service_exclusions != null ){
197 
198 			List<Long> sex = new ArrayList<Long>();
199 
200 			for (Integer i: service_exclusions){
201 
202 				sex.add( i.longValue());
203 			}
204 
205 			map.put( "vg_sex", sex );
206 		}
207 	}
208 
209 	protected void
init()210 	init()
211 	{
212 		service_map.clear();
213 
214 		addService( SERVICE_SEARCH, 			URL_PREFIX + "search?q=" );
215 		addService( SERVICE_XSEARCH, 			URL_PREFIX + "xsearch/index.php?q=" );
216 		addService( SERVICE_RPC, 				RPC_ADDRESS );
217 		addService( SERVICE_BIG_BROWSE, 		URL_PREFIX + "browse.start?" );
218 		addService( SERVICE_PUBLISH, 			URL_PREFIX + "publish.start?" );
219 		addService( SERVICE_WELCOME, 			URL_PREFIX + "welcome.start?" );
220 		addService( SERVICE_ABOUT, 				URL_PREFIX + "about.start?" );
221 		addService( SERVICE_PUBLISH_NEW, 		URL_PREFIX + "publishnew.start?" );
222 		addService( SERVICE_PUBLISH_ABOUT, 		URL_PREFIX + "publishinfo.start" );
223 		addService( SERVICE_CONTENT_DETAILS, 	URL_PREFIX + "details/" );
224 		addService( SERVICE_COMMENT,			URL_PREFIX + "comment/" );
225 		addService( SERVICE_PROFILE,			URL_PREFIX + "profile/" );
226 		addService( SERVICE_TORRENT_DOWNLOAD,	URL_PREFIX + "download/" );
227 		addService( SERVICE_SITE,				URL_PREFIX );
228 		addService( SERVICE_SUPPORT,			URL_EXT_PREFIX + "support/" );
229 		addService( SERVICE_LOGIN,				URL_PREFIX + "login.start?" );
230 		addService( SERVICE_LOGOUT,				URL_PREFIX + "logout.start?" );
231 		addService( SERVICE_REGISTER,			URL_PREFIX + "register.start?" );
232 		addService( SERVICE_MY_PROFILE,			URL_PREFIX + "profile.start?" );
233 		addService( SERVICE_MY_ACCOUNT,			URL_PREFIX + "account.start?" );
234 		addService( SERVICE_SITE_RELATIVE,		URL_PREFIX );
235 		addService( SERVICE_EXT_SITE_RELATIVE,		URL_EXT_PREFIX );
236 		addService( SERVICE_ADD_FRIEND,			URL_PREFIX + "user/AddFriend.html?" );
237 		addService( SERVICE_SUBSCRIPTION,		URL_PREFIX + "xsearch/index.php?" );
238 
239 		addService( SERVICE_AUTHORIZE,			URL_PREFIX + "ip.start?" );
240 		addService( SERVICE_GET_ICON,			URL_ICON );
241 
242 		addService( SERVICE_PREPLAYBACK,		URL_PREFIX + "emp/load/" );
243 		addService( SERVICE_POSTPLAYBACK, 		URL_PREFIX + "emp/recommend/" );
244 		addService( SERVICE_SIDEBAR_CLOSE, 		URL_PREFIX + "sidebar.close" );
245 		addService( SERVICE_IDENTIFY,			"http://pixel.quantserve.com/pixel/p-64Ix1G_SXwOa-.gif" );
246 
247 		if ( URL_RELAY_RPC != null ){
248 
249 			addService( SERVICE_RELAY_RPC, 		URL_RELAY_RPC );
250 		}
251 
252 		if ( URL_AUTHORIZED_RPC != null ){
253 
254 			addService( SERVICE_AUTH_RPC, 		URL_AUTHORIZED_RPC );
255 		}
256 
257 		if ( URL_FAQ != null ){
258 
259 			addService( SERVICE_FAQ,			URL_FAQ );
260 			addService( SERVICE_FAQ_TOPIC,		URL_FAQ );
261 		}
262 
263 		if ( URL_BLOG != null ){
264 
265 			addService( SERVICE_BLOG,			URL_BLOG );
266 		}
267 
268 		if ( URL_FORUMS != null ){
269 
270 			addService( SERVICE_FORUMS,			URL_FORUMS );
271 		}
272 
273 		if ( URL_WIKI != null ){
274 
275 			addService( SERVICE_WIKI,			URL_WIKI );
276 		}
277 	}
278 
279 	protected void
addService( int type, String url_str )280 	addService(
281 		int		type,
282 		String	url_str )
283 	{
284 		 service_map.put( type, url_str );
285 	}
286 
287 	protected Set<Integer>
getServiceExclusions()288 	getServiceExclusions()
289 	{
290 		return( service_exclusions );
291 	}
292 
293 	public Object
getProperty( int property )294 	getProperty(
295 		int property )
296 	{
297 		if ( property == PROPERTY_SITE_HOST ){
298 
299 			return( SITE_HOST );
300 
301 		}else if ( property == PROPERTY_REMOVEABLE ){
302 
303 			return( getID() != CONTENT_NETWORK_VUZE );
304 
305 		}else if ( property == PROPERTY_ORDER ){
306 
307 			return( String.valueOf( getID()));
308 
309 		}else{
310 
311 			debug( "Unknown property" );
312 
313 			return( null );
314 		}
315 	}
316 
317 	public boolean
isServiceSupported( int service_type )318 	isServiceSupported(
319 		int service_type )
320 	{
321 		if ( service_exclusions != null && service_exclusions.contains( service_type )){
322 
323 			return( false );
324 		}
325 
326 		return( service_map.get( service_type ) != null );
327 	}
328 
329 	public String
getServiceURL( int service_type )330 	getServiceURL(
331 		int			service_type )
332 	{
333 		return( getServiceURL( service_type, new Object[0]));
334 	}
335 
336 
337 	public String
getServiceURL( int service_type, Object[] params )338 	getServiceURL(
339 		int			service_type,
340 		Object[]	params )
341 	{
342 		if ( service_exclusions != null && service_exclusions.contains( service_type )){
343 
344 			debug( "Service type '" + service_type + "' is excluded" );
345 
346 			return( null );
347 		}
348 
349 		String	base = service_map.get( service_type );
350 
351 		if ( base == null ){
352 
353 			debug( "Unknown service type '" + service_type + "'" );
354 
355 			return( null );
356 		}
357 
358 		switch( service_type ){
359 
360 			case SERVICE_SEARCH:{
361 
362 				String	query = (String)params[0];
363 
364 				return(	base +
365 						UrlUtils.encode(query) +
366 						"&" + URL_SUFFIX +
367 						"&rand=" + SystemTime.getCurrentTime());
368 			}
369 
370 			case SERVICE_XSEARCH:{
371 
372 				String	query 			= (String)params[0];
373 				boolean	to_subscribe	= (Boolean)params[1];
374 
375 				String url_str =
376 							base +
377 							UrlUtils.encode(query) +
378 							"&" + URL_SUFFIX +
379 							"&rand=" + SystemTime.getCurrentTime();
380 
381 				if ( to_subscribe ){
382 
383 					url_str += "&createSubscription=1";
384 				}
385 
386 				String	extension_key = getExtensionKey();
387 
388 				if ( extension_key != null ){
389 
390 					url_str += "&extension_key=" + UrlUtils.encode( extension_key );
391 				}
392 
393 				url_str += "&fud=" + UrlUtils.encode( MetaSearchManagerFactory.getSingleton().getMetaSearch().getFUD());
394 
395 				return( url_str );
396 			}
397 			case SERVICE_CONTENT_DETAILS:{
398 
399 				String	hash 		= (String)params[0];
400 				String	client_ref 	= (String)params[1];
401 
402 				String url_str = base + hash + ".html?" + URL_SUFFIX;
403 
404 				if ( client_ref != null ){
405 
406 					url_str += "&client_ref=" +  UrlUtils.encode( client_ref );
407 				}
408 
409 				return( url_str );
410 			}
411 			case SERVICE_POSTPLAYBACK:
412 			case SERVICE_PREPLAYBACK:{
413 
414 				String	hash 		= (String)params[0];
415 
416 				String url_str = base + hash + "?" + URL_SUFFIX;
417 
418 				return( url_str );
419 			}
420 			case SERVICE_COMMENT:{
421 
422 				String	hash 		= (String)params[0];
423 
424 				return( base + hash + ".html?" + URL_SUFFIX	+ "&rnd=" + Math.random());
425 			}
426 			case SERVICE_PROFILE:{
427 
428 				String	login_id 	= (String)params[0];
429 				String	client_ref 	= (String)params[1];
430 
431 				return( base + UrlUtils.encode( login_id ) + "?" + URL_SUFFIX + "&client_ref=" +  UrlUtils.encode( client_ref ));
432 			}
433 			case SERVICE_TORRENT_DOWNLOAD:{
434 
435 				String	hash 		= (String)params[0];
436 				String	client_ref 	= (String)params[1];
437 
438 				String url_str = base + hash + ".torrent";
439 
440 				if ( client_ref != null ){
441 
442 					url_str += "?referal=" +  UrlUtils.encode( client_ref );
443 				}
444 
445 				url_str = appendURLSuffix(url_str, false, true);
446 
447 				return( url_str );
448 			}
449 			case SERVICE_FAQ_TOPIC:{
450 
451 				String	topic 		= (String)params[0];
452 
453 				return( base + topic );
454 			}
455 			case SERVICE_LOGIN:{
456 
457 				String	message 		= (String)params[0];
458 
459 				if ( message == null || message.length() == 0 ){
460 
461 					base += URL_SUFFIX;
462 
463 				}else{
464 
465 					base += "msg=" + UrlUtils.encode( message );
466 
467 					base += "&" + URL_SUFFIX;
468 				}
469 
470 				return( base );
471 			}
472 			case SERVICE_MY_PROFILE:
473 			case SERVICE_MY_ACCOUNT:{
474 
475 				base += URL_SUFFIX + "&rand=" + SystemTime.getCurrentTime();
476 
477 				return( base );
478 			}
479 			case SERVICE_SITE_RELATIVE:{
480 
481 				String	relative_url 	= (String)params[0];
482 				boolean	append_suffix	= (Boolean)params[1];
483 
484 				base += relative_url.startsWith("/")?relative_url.substring(1):relative_url;
485 
486 				if ( append_suffix ){
487 
488 					base = appendURLSuffix( base, false, true );
489 				}
490 
491 				return( base );
492 			}
493 			case SERVICE_EXT_SITE_RELATIVE:{
494 
495 				String	relative_url 	= (String)params[0];
496 				boolean	append_suffix	= (Boolean)params[1];
497 
498 				base += relative_url.startsWith("/")?relative_url.substring(1):relative_url;
499 
500 				if ( append_suffix ){
501 
502 					base = appendURLSuffix( base, false, true );
503 				}
504 
505 				base = base.replaceAll( "&vzemb=1", "" );
506 
507 				return( base );
508 			}
509 			case SERVICE_ADD_FRIEND:{
510 
511 				String	colour 	= (String)params[0];
512 
513 				base += "ts=" + Math.random() + "&bg_color=" + colour + "&" + URL_SUFFIX;
514 
515 				return( base );
516 			}
517 			case SERVICE_SUBSCRIPTION:{
518 
519 				String	subs_id 	= (String)params[0];
520 
521 				base += "subscription=" + subs_id + "&" + URL_SUFFIX;
522 
523 				return( base );
524 			}
525 			case SERVICE_AUTHORIZE:{
526 
527 				String sourceRef = params.length > 0 ? (String) params[0] : null;
528 
529 				if (sourceRef != null) {
530 
531 					base += "sourceref=" + UrlUtils.encode(sourceRef) + "&" + URL_SUFFIX;
532 				}
533 
534 				return( base );
535 			}
536 			case SERVICE_WELCOME:{
537 				String installID = COConfigurationManager.getStringParameter("install.id", "null");
538 				if (installID.length() == 0) {
539 					installID = "blank";
540 				}
541 				base += "iid=" + UrlUtils.encode(installID) + "&" + URL_SUFFIX;
542 				return( base );
543 			}
544 
545 			case SERVICE_BIG_BROWSE:
546 			case SERVICE_PUBLISH:
547 			case SERVICE_LOGOUT:
548 			case SERVICE_REGISTER:{
549 
550 				 return( base + URL_SUFFIX );
551 			}
552 			case SERVICE_ABOUT: {
553 				// no azid needed (+ makes URL ugly)
554 				return base + "azv=" + Constants.AZUREUS_VERSION + "&locale="
555 						+ MessageText.getCurrentLocale().toString();
556 			}
557 			default:{
558 
559 				return( appendURLSuffix( base, false, true) );
560 			}
561 		}
562 	}
563 
564 	public String
appendURLSuffix( String url_in, boolean for_post, boolean include_azid )565 	appendURLSuffix(
566 		String 		url_in,
567 		boolean		for_post,
568 		boolean 	include_azid )
569 	{
570 		if ( url_in.indexOf( "vzemb=" ) != -1 ){
571 
572 				// already present
573 
574 			return( url_in );
575 		}
576 
577 
578 		String suffix = URL_SUFFIX;
579 
580 		if ( !include_azid ){
581 
582 			suffix = suffix.replaceAll( "azid=.*?&", "" );
583 		}
584 
585 		if ( for_post ){
586 
587 			if ( url_in.length() == 0 ){
588 
589 				return( suffix );
590 
591 			}else{
592 
593 				return( url_in + "&" + suffix  );
594 			}
595 		}else{
596 
597 			if ( url_in.indexOf("?") >= 0 ){
598 
599 				return( url_in + "&" + suffix );
600 
601 			}else{
602 
603 				return( url_in + "?" + suffix );
604 			}
605 		}
606 	}
607 
608 	private String
getExtensionKey()609 	getExtensionKey()
610 	{
611 		FeatureManager fm = PluginInitializer.getDefaultInterface().getUtilities().getFeatureManager();
612 
613 		FeatureDetails[] fds = fm.getFeatureDetails( "core" );
614 
615 		for ( FeatureDetails fd: fds ){
616 
617 			if ( !fd.hasExpired()){
618 
619 				String finger_print = (String)fd.getProperty( FeatureDetails.PR_FINGERPRINT );
620 
621 				if ( finger_print != null ){
622 
623 					return( fd.getLicence().getShortID() + "-" + finger_print );
624 				}
625 			}
626 		}
627 
628 		fds = fm.getFeatureDetails( "no_ads" );
629 
630 		for ( FeatureDetails fd: fds ){
631 
632 			if ( !fd.hasExpired()){
633 
634 				String finger_print = (String)fd.getProperty( FeatureDetails.PR_FINGERPRINT );
635 
636 				if ( finger_print != null ){
637 
638 					return( fd.getLicence().getShortID() + "-" + finger_print );
639 				}
640 			}
641 		}
642 
643 		return( null );
644 	}
645 }
646