Merge lp:~jamesh/unity-lens-applications/scope-previews into lp:~unity-team/unity-lens-applications/libunity7-compatible

Proposed by James Henstridge
Status: Merged
Approved by: Michal Hruby
Approved revision: 348
Merged at revision: 344
Proposed branch: lp:~jamesh/unity-lens-applications/scope-previews
Merge into: lp:~unity-team/unity-lens-applications/libunity7-compatible
Diff against target: 615 lines (+313/-256)
1 file modified
src/daemon.vala (+313/-256)
To merge this branch: bzr merge lp:~jamesh/unity-lens-applications/scope-previews
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Michal Hruby (community) Approve
Review via email: mp+161534@code.launchpad.net

Commit message

Add screenshots to local scope previews with information obtained from the software center, escape markup characters in descriptions and don't allow the user to disable the applications scope.

Description of the change

When creating previews for local scopes, look up the package name in the software center index (requires scopes to be included in the app-install data) and then query the data provider for screenshots to include in the preview. This

As the preview() method was getting quite long, I also took the opportunity to split it into the app preview and scope preview cases into their own methods.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
344. By James Henstridge

Escape special characters in the scope description when producing
previews.

345. By James Henstridge

Don't include scope description in comment field of search results.

346. By James Henstridge

Don't show the enable/disable buttons in the preview of the applications
scope.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
347. By James Henstridge

Merge from libunity7-compatible, fixing conflict

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
348. By James Henstridge

Also remove the disable action for the home scope.

Revision history for this message
Michal Hruby (mhr3) wrote :

LGTM

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/daemon.vala'
--- src/daemon.vala 2013-04-30 18:46:48 +0000
+++ src/daemon.vala 2013-05-01 19:21:29 +0000
@@ -1080,7 +1080,6 @@
1080 var uri = @"scope://$(info.desktop_file)";1080 var uri = @"scope://$(info.desktop_file)";
1081 var name = info.application_name;1081 var name = info.application_name;
1082 var icon_hint = info.icon;1082 var icon_hint = info.icon;
1083 var comment = info.description;
1084 var category = info.desktop_file in disabled_scope_ids ?1083 var category = info.desktop_file in disabled_scope_ids ?
1085 Category.AVAILABLE : Category.INSTALLED;1084 Category.AVAILABLE : Category.INSTALLED;
10861085
@@ -1103,7 +1102,7 @@
1103 ResultType.DEFAULT,1102 ResultType.DEFAULT,
1104 "application/x-unity-scope",1103 "application/x-unity-scope",
1105 name != "" ? name : uri,1104 name != "" ? name : uri,
1106 comment,1105 "",
1107 "", // dnd_uri ?!1106 "", // dnd_uri ?!
1108 empty_asv);1107 empty_asv);
1109 }1108 }
@@ -1310,282 +1309,340 @@
13101309
1311 public Unity.Preview preview (string uri)1310 public Unity.Preview preview (string uri)
1312 {1311 {
1313 Unity.ApplicationPreview? preview = null;1312 Unity.Preview? preview = null;
1314
1315 string pkgname = "";
1316 string appname = "";
1317 bool installed = uri.has_prefix ("application://");1313 bool installed = uri.has_prefix ("application://");
1318 bool is_scope = uri.has_prefix ("scope://");1314 bool is_scope = uri.has_prefix ("scope://");
13191315
1320 if (installed || uri.has_prefix ("unity-install://"))1316 if (installed || uri.has_prefix ("unity-install://"))
1321 {1317 {
1322 string desktopfile = null;1318 preview = make_app_preview (uri, installed);
1323 if (installed)1319 }
1324 {1320 else if (is_scope)
1325 desktopfile = uri.substring (14); //remove "application://" prefix1321 {
13261322 preview = make_scope_preview (uri);
1327 // de-mangle desktop file names back to what S-C expects1323 }
1328 if (sc_mangler.contains (desktopfile))1324 return preview;
1329 {1325 }
1330 desktopfile = sc_mangler.get (desktopfile);1326
1331 }1327 private SoftwareCenterData.AppDetailsData get_app_details (string appname, string pkgname) throws Error
13321328 {
1333 Unity.Package.PackageInfo pkginfo = pkgsearcher.get_by_desktop_file (desktopfile);1329 if (sc_data_provider == null)
1334 if (pkginfo != null)1330 {
1335 {1331 sc_data_provider = new SoftwareCenterDataCache (TOP_RATED_ITEMS_CACHE_LIFETIME);
1336 appname = pkginfo.application_name;1332 sc_data_provider.connect_to ();
1337 pkgname = pkginfo.package_name;1333 }
1338 }1334
1339 }1335 debug ("Requesting pkg info: %s, %s\n", pkgname, appname);
1340 else // unity-install1336 return sc_data_provider.get_app_details (appname, pkgname);
1341 {1337 }
1342 string app = uri.substring (16); //remove "unity-install://" prefix1338
1343 string[] parts = app.split ("/");1339 private Unity.Preview make_app_preview (string uri, bool installed)
1344 if (parts.length > 1)1340 {
1345 {1341 Unity.ApplicationPreview? preview = null;
1346 pkgname = parts[0];1342 string desktopfile = null;
1347 appname = parts[1];1343 string pkgname = "";
1348 }1344 string appname = "";
1349 }1345
13501346 if (installed)
1351 if (pkgname != "")1347 {
1352 {1348 desktopfile = uri.substring (14); //remove "application://" prefix
1349
1350 // de-mangle desktop file names back to what S-C expects
1351 if (sc_mangler.contains (desktopfile))
1352 {
1353 desktopfile = sc_mangler.get (desktopfile);
1354 }
1355
1356 Unity.Package.PackageInfo pkginfo = pkgsearcher.get_by_desktop_file (desktopfile);
1357 if (pkginfo != null)
1358 {
1359 appname = pkginfo.application_name;
1360 pkgname = pkginfo.package_name;
1361 }
1362 }
1363 else // unity-install
1364 {
1365 string app = uri.substring (16); //remove "unity-install://" prefix
1366 string[] parts = app.split ("/");
1367 if (parts.length > 1)
1368 {
1369 pkgname = parts[0];
1370 appname = parts[1];
1371 }
1372 }
1373
1374 if (pkgname != "")
1375 {
1376 try {
1377 var details = get_app_details (appname, pkgname);
1378
1379 Icon? icon = null;
1380 if (installed)
1381 icon = new GLib.ThemedIcon (details.icon);
1382 else
1383 {
1384 icon = find_pkg_icon (null, details.icon);
1385 if (icon.to_string () == GENERIC_APP_ICON && details.icon_url != null && details.icon_url != "")
1386 {
1387 icon = new GLib.FileIcon (File.new_for_uri (details.icon_url));
1388 }
1389 }
1390
1391 Icon? screenshot = null;
1392
1393 if (details.screenshot != null)
1394 {
1395 File scr_file = File.new_for_uri (details.screenshot);
1396 screenshot = new FileIcon (scr_file);
1397 }
1398
1399 string subtitle = "";
1400 if (details.version != "")
1401 subtitle = _("Version %s").printf (details.version);
1402 if (details.size > 0)
1403 {
1404 if (subtitle != "")
1405 subtitle += ", ";
1406 subtitle += ("Size %s").printf (GLib.format_size (details.size));
1407 }
1408 preview = new Unity.ApplicationPreview (details.name, subtitle, details.description, icon, screenshot);
1409 preview.license = details.license;
1410
1411 init_ratings_db ();
1412 if (ratings != null)
1413 {
1414 Unity.Ratings.Result result;
1415 ratings.query (pkgname, out result);
1416 preview.set_rating (result.average_rating / 5.0f, result.total_rating);
1417 }
1418
1419 if (details.hardware_requirements != "")
1420 preview.add_info (new InfoHint ("hardware-requirements", _("Hardware requirements"), null, details.hardware_requirements));
1421
1422 if (uri.has_prefix ("unity-install://")) // application needs to be purchased/installed
1423 {
1424 // uninstalled and not purchased before
1425 if (details.pkg_state == SoftwareCenterData.PackageState.NEEDS_PURCHASE)
1426 {
1427 var buy_action = new Unity.PreviewAction ("buy", _("Buy"), null);
1428 if (details.price != null && details.price != "")
1429 {
1430 buy_action.extra_text = details.price;
1431 }
1432
1433 buy_action.activated.connect (start_software_center);
1434 preview.add_action (buy_action);
1435 }
1436 else // uninstalled, purchased before
1437 {
1438
1439 Unity.PreviewAction install_action = null;
1440 if (details.raw_price == null || details.raw_price == "")
1441 {
1442 install_action = new Unity.PreviewAction ("install", _("Free Download"), null);
1443 install_action.activated.connect (app_preview_install);
1444 }
1445 else
1446 {
1447 install_action = new Unity.PreviewAction ("install", _("Install"), null);
1448 install_action.activated.connect (start_software_center);
1449 }
1450 preview.add_action (install_action);
1451 }
1452
1453 if (details.website != null && details.website != "")
1454 {
1455 preview_developer_website = details.website;
1456 var website_action = new Unity.PreviewAction ("website", _("Developer Site"), null);
1457 website_action.activated.connect (app_preview_website);
1458 preview.add_action (website_action);
1459 }
1460 }
1461 else // application is already installed
1462 {
1463 preview.add_info (new InfoHint ("date-installed", _("Installed on"), null, details.installation_date));
1464 var launch_action = new Unity.PreviewAction ("launch", _("Launch"), null);
1465 preview.add_action (launch_action);
1466 if (!details.is_desktop_dependency)
1467 {
1468 var uninstall_action = new Unity.PreviewAction ("uninstall", _("Uninstall"), null);
1469 uninstall_action.activated.connect (app_preview_uninstall);
1470 preview.add_action (uninstall_action);
1471 }
1472 }
1473
1474 preview_installable_desktop_file = details.desktop_file;
1475 preview_installable_icon_file = details.icon;
1476 }
1477 catch (Error e)
1478 {
1479 warning ("Failed to get package details for '%s': %s", uri, e.message);
1480 preview = null;
1481 }
1482 }
1483
1484 // xapian db doesn't know this .desktop file or S-C dbus data provider fails,
1485 // fallback to DesktopAppInfo (based on installed .desktop file) if available
1486 if (preview == null && desktopfile != null)
1487 {
1488 var app_info = new DesktopAppInfo (desktopfile);
1489 if (app_info != null)
1490 {
1491 preview = new Unity.ApplicationPreview (app_info.get_display_name (), "", app_info.get_description () ?? "", app_info.get_icon (), null);
1492 var launch_action = new Unity.PreviewAction ("launch", _("Launch"), null);
1493 preview.add_action (launch_action);
1494 }
1495 }
1496
1497 if (preview == null)
1498 {
1499 warning ("No pksearcher nor desktop app info for '%s'", uri);
1500 }
1501 return preview;
1502 }
1503
1504 private Unity.Preview make_scope_preview(string uri)
1505 {
1506 Unity.ApplicationPreview? preview = null;
1507 var scope_id = uri.substring (8);
1508 bool scope_disabled = scope_id in disabled_scope_ids;
1509
1510 // figure out if the scope is remote
1511 bool is_remote_scope = false;
1512 var info = scopesearcher.get_by_desktop_file (scope_id);
1513
1514 Dee.ModelIter found_iter = null;
1515 if (info == null)
1516 {
1517 var iter = remote_scopes_model.get_first_iter ();
1518 var end_iter = remote_scopes_model.get_last_iter ();
1519 while (iter != end_iter)
1520 {
1521 if (remote_scopes_model.get_string (iter, 0) == scope_id)
1522 {
1523 is_remote_scope = true;
1524 found_iter = iter;
1525 break;
1526 }
1527 iter = remote_scopes_model.next (iter);
1528 }
1529 }
1530
1531 if (is_remote_scope)
1532 {
1533 var name = remote_scopes_model.get_string (found_iter, 1);
1534 if (name == null || name == "")
1535 name = remote_scopes_model.get_string (found_iter, 0);
1536 var description = remote_scopes_model.get_string (found_iter, 2);
1537 if (description != null)
1538 description = Markup.escape_text(description);
1539 Icon? icon = null;
1540 Icon? screenshot = null;
1541 var icon_hint = remote_scopes_model.get_string (found_iter, 3);
1542 var screenshot_url = remote_scopes_model.get_string (found_iter, 4);
1543 try
1544 {
1545 if (icon_hint != "") icon = Icon.new_for_string (icon_hint);
1546 if (screenshot_url != "") screenshot = Icon.new_for_string (screenshot_url);
1547 }
1548 catch (Error err)
1549 {
1550 warning ("%s", err.message);
1551 }
1552
1553 if (icon == null) icon = get_default_scope_icon ();
1554
1555 preview = new Unity.ApplicationPreview (name,
1556 "",
1557 description,
1558 icon,
1559 screenshot);
1560 }
1561 else if (info != null)
1562 {
1563 var name = info.application_name;
1564 if (name == null || name == "")
1565 name = info.desktop_file;
1566 var subtitle = "";
1567 var description = info.description;
1568 if (description != null)
1569 description = Markup.escape_text(description);
1570 Icon? icon = null;
1571 Icon? screenshot = null;
1572 try
1573 {
1574 if (info.icon != null && info.icon != "")
1575 icon = Icon.new_for_string (info.icon);
1576 }
1577 catch (Error err)
1578 {
1579 warning ("%s", err.message);
1580 }
1581 if (icon == null)
1582 icon = get_default_scope_icon ();
1583
1584 // de-mangle desktop file names back to what S-C expects
1585 string mangled_id;
1586 if (sc_mangler.contains (scope_id))
1587 {
1588 mangled_id = sc_mangler.get (scope_id);
1589 }
1590 else
1591 {
1592 mangled_id = scope_id;
1593 }
1594
1595 Unity.Package.PackageInfo pkginfo = pkgsearcher.get_by_desktop_file (mangled_id);
1596 if (pkginfo != null)
1597 {
1598 SoftwareCenterData.AppDetailsData? details;
1353 try {1599 try {
1354 if (sc_data_provider == null)1600 details = get_app_details(pkginfo.application_name,
1355 {1601 pkginfo.package_name);
1356 sc_data_provider = new SoftwareCenterDataCache (TOP_RATED_ITEMS_CACHE_LIFETIME);1602 } catch (Error e) {
1357 sc_data_provider.connect_to ();1603 details = null;
1358 }1604 }
13591605 if (details != null) {
1360 debug ("Requesting pkg info: %s, %s\n", pkgname, appname);1606 if (details.version != "")
1361 var details = sc_data_provider.get_app_details (appname, pkgname);1607 subtitle = _("Version %s").printf (details.version);
1362
1363 Icon? icon = null;
1364 if (installed)
1365 icon = new GLib.ThemedIcon (details.icon);
1366 else
1367 {
1368 icon = find_pkg_icon (null, details.icon);
1369 if (icon.to_string () == GENERIC_APP_ICON && details.icon_url != null && details.icon_url != "")
1370 {
1371 icon = new GLib.FileIcon (File.new_for_uri (details.icon_url));
1372 }
1373 }
1374
1375 Icon? screenshot = null;
1376
1377 if (details.screenshot != null)1608 if (details.screenshot != null)
1378 {1609 {
1379 File scr_file = File.new_for_uri (details.screenshot);1610 File scr_file = File.new_for_uri (details.screenshot);
1380 screenshot = new FileIcon (scr_file);1611 screenshot = new FileIcon (scr_file);
1381 }1612 }
13821613 }
1383 string subtitle = "";1614 }
1384 if (details.version != "")1615
1385 subtitle = _("Version %s").printf (details.version);1616 preview = new Unity.ApplicationPreview (name,
1386 if (details.size > 0)1617 subtitle,
1387 {1618 description,
1388 if (subtitle != "")1619 icon,
1389 subtitle += ", ";1620 screenshot);
1390 subtitle += ("Size %s").printf (GLib.format_size (details.size));
1391 }
1392 preview = new Unity.ApplicationPreview (details.name, subtitle, details.description, icon, screenshot);
1393 preview.license = details.license;
1394
1395 init_ratings_db ();
1396 if (ratings != null)
1397 {
1398 Unity.Ratings.Result result;
1399 ratings.query (pkgname, out result);
1400 preview.set_rating (result.average_rating / 5.0f, result.total_rating);
1401 }
1402
1403 if (details.hardware_requirements != "")
1404 preview.add_info (new InfoHint ("hardware-requirements", _("Hardware requirements"), null, details.hardware_requirements));
1405
1406 if (uri.has_prefix ("unity-install://")) // application needs to be purchased/installed
1407 {
1408 // uninstalled and not purchased before
1409 if (details.pkg_state == SoftwareCenterData.PackageState.NEEDS_PURCHASE)
1410 {
1411 var buy_action = new Unity.PreviewAction ("buy", _("Buy"), null);
1412 if (details.price != null && details.price != "")
1413 {
1414 buy_action.extra_text = details.price;
1415 }
1416
1417 buy_action.activated.connect (start_software_center);
1418 preview.add_action (buy_action);
1419 }
1420 else // uninstalled, purchased before
1421 {
1422
1423 Unity.PreviewAction install_action = null;
1424 if (details.raw_price == null || details.raw_price == "")
1425 {
1426 install_action = new Unity.PreviewAction ("install", _("Free Download"), null);
1427 install_action.activated.connect (app_preview_install);
1428 }
1429 else
1430 {
1431 install_action = new Unity.PreviewAction ("install", _("Install"), null);
1432 install_action.activated.connect (start_software_center);
1433 }
1434 preview.add_action (install_action);
1435 }
1436
1437 if (details.website != null && details.website != "")
1438 {
1439 preview_developer_website = details.website;
1440 var website_action = new Unity.PreviewAction ("website", _("Developer Site"), null);
1441 website_action.activated.connect (app_preview_website);
1442 preview.add_action (website_action);
1443 }
1444 }
1445 else // application is already installed
1446 {
1447 preview.add_info (new InfoHint ("date-installed", _("Installed on"), null, details.installation_date));
1448 var launch_action = new Unity.PreviewAction ("launch", _("Launch"), null);
1449 preview.add_action (launch_action);
1450 if (!details.is_desktop_dependency)
1451 {
1452 var uninstall_action = new Unity.PreviewAction ("uninstall", _("Uninstall"), null);
1453 uninstall_action.activated.connect (app_preview_uninstall);
1454 preview.add_action (uninstall_action);
1455 }
1456 }
1457
1458 preview_installable_desktop_file = details.desktop_file;
1459 preview_installable_icon_file = details.icon;
1460 }
1461 catch (Error e)
1462 {
1463 warning ("Failed to get package details for '%s': %s", uri, e.message);
1464 preview = null;
1465 }
1466 }
1467
1468 // xapian db doesn't know this .desktop file or S-C dbus data provider fails,
1469 // fallback to DesktopAppInfo (based on installed .desktop file) if available
1470 if (preview == null && desktopfile != null)
1471 {
1472 var app_info = new DesktopAppInfo (desktopfile);
1473 if (app_info != null)
1474 {
1475 preview = new Unity.ApplicationPreview (app_info.get_display_name (), "", app_info.get_description () ?? "", app_info.get_icon (), null);
1476 var launch_action = new Unity.PreviewAction ("launch", _("Launch"), null);
1477 preview.add_action (launch_action);
1478 }
1479 }
1480
1481 if (preview == null)
1482 {
1483 warning ("No pksearcher nor desktop app info for '%s'", uri);
1484 }
1485 }1621 }
1486 else if (is_scope)1622 if (preview != null && scope_id != "home.scope" &&
1623 scope_id != "applications.scope")
1487 {1624 {
1488 var scope_id = uri.substring (8);1625 PreviewAction action;
1489 bool scope_disabled = scope_id in disabled_scope_ids;1626 preview.set_rating(-1.0f, 0);
14901627 if (scope_disabled)
1491 // figure out if the scope is remote1628 {
1492 bool is_remote_scope = false;1629 action = new Unity.PreviewAction ("enable-scope", _("Enable"), null);
1493 var info = scopesearcher.get_by_desktop_file (scope_id);1630 action.activated.connect (() =>
1494
1495 Dee.ModelIter found_iter = null;
1496 if (info == null)
1497 {
1498 var iter = remote_scopes_model.get_first_iter ();
1499 var end_iter = remote_scopes_model.get_last_iter ();
1500 while (iter != end_iter)
1501 {
1502 if (remote_scopes_model.get_string (iter, 0) == scope_id)
1503 {
1504 is_remote_scope = true;
1505 found_iter = iter;
1506 break;
1507 }
1508 iter = remote_scopes_model.next (iter);
1509 }
1510 }
1511
1512 if (is_remote_scope)
1513 {
1514 var name = remote_scopes_model.get_string (found_iter, 1);
1515 if (name == null || name == "")
1516 name = remote_scopes_model.get_string (found_iter, 0);
1517 var description = remote_scopes_model.get_string (found_iter, 2);
1518 Icon? icon = null;
1519 Icon? screenshot = null;
1520 var icon_hint = remote_scopes_model.get_string (found_iter, 3);
1521 var screenshot_url = remote_scopes_model.get_string (found_iter, 4);
1522 try
1523 {
1524 if (icon_hint != "") icon = Icon.new_for_string (icon_hint);
1525 if (screenshot_url != "") screenshot = Icon.new_for_string (screenshot_url);
1526 }
1527 catch (Error err)
1528 {
1529 warning ("%s", err.message);
1530 }
1531
1532 if (icon == null) icon = get_default_scope_icon ();
1533
1534 preview = new Unity.ApplicationPreview (name,
1535 "",
1536 description,
1537 icon,
1538 screenshot);
1539 }
1540 else if (info != null)
1541 {
1542 var name = info.application_name;
1543 if (name == null || name == "")
1544 name = info.desktop_file;
1545 // XXX: add this to package info.
1546 var description = info.description;
1547 Icon? icon = null;
1548 try
1549 {
1550 if (info.icon != null && info.icon != "")
1551 icon = Icon.new_for_string (info.icon);
1552 }
1553 catch (Error err)
1554 {
1555 warning ("%s", err.message);
1556 }
1557 if (icon == null)
1558 icon = get_default_scope_icon ();
1559
1560 preview = new Unity.ApplicationPreview (name,
1561 "",
1562 description,
1563 icon,
1564 null);
1565 }
1566 if (preview != null) {
1567 PreviewAction action;
1568 preview.set_rating(-1.0f, 0);
1569 if (scope_disabled)
1570 {
1571 action = new Unity.PreviewAction ("enable-scope", _("Enable"), null);
1572 action.activated.connect (() =>
1573 {1631 {
1574 enable_scope (scope_id);1632 enable_scope (scope_id);
1575 return new ActivationResponse.with_preview (this.preview (uri));1633 return new ActivationResponse.with_preview (this.preview (uri));
1576 });1634 });
1577 }1635 }
1578 else1636 else
1579 {1637 {
1580 action = new Unity.PreviewAction ("disable-scope", _("Disable"), null);1638 action = new Unity.PreviewAction ("disable-scope", _("Disable"), null);
1581 action.activated.connect (() =>1639 action.activated.connect (() =>
1582 {1640 {
1583 disable_scope (scope_id);1641 disable_scope (scope_id);
1584 return new ActivationResponse.with_preview (this.preview (uri));1642 return new ActivationResponse.with_preview (this.preview (uri));
1585 });1643 });
1586 }
1587 preview.add_action (action);
1588 }1644 }
1645 preview.add_action (action);
1589 }1646 }
1590 return preview;1647 return preview;
1591 }1648 }

Subscribers

People subscribed via source and target branches

to all changes: