text:
namespace {

// A prefix to apply to all features which Chrome OS platform-side code wishes
// to check.
// This prefix must *only* be applied to features on the platform side, and no
// |base::Feature|s should be defined with this prefix.
// A presubmit will enforce that no |base::Feature|s will be defined with this
// prefix.
// TODO(https://crbug.com/1263068): Add the aforementioned presubmit.
constexpr char kCrOSLateBootFeaturePrefix[] = "CrOSLateBoot";

void SendResponse(dbus::MethodCall* method_call,
                  dbus::ExportedObject::ResponseSender response_sender,
                  bool answer,
                  const std::string& reason = std::string()) {
  std::unique_ptr<dbus::Response> response =
      dbus::Response::FromMethodCall(method_call);
  dbus::MessageWriter writer(response.get());
  writer.AppendBool(answer);
  if (!reason.empty())
    writer.AppendString(reason);
  std::move(response_sender).Run(std::move(response));
}

Profile* GetSenderProfile(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender* response_sender) {
  dbus::MessageReader reader(method_call);
  std::string user_id_hash;

  if (!reader.PopString(&user_id_hash)) {
    LOG(ERROR) << "Failed to pop user_id_hash from incoming message.";
    std::move(*response_sender)
        .Run(dbus::ErrorResponse::FromMethodCall(method_call,
                                                 DBUS_ERROR_INVALID_ARGS,
                                                 "No user_id_hash string arg"));
    return nullptr;
  }

  if (user_id_hash.empty())
    return ProfileManager::GetActiveUserProfile();

  return g_browser_process->profile_manager()->GetProfileByPath(
      ash::ProfileHelper::GetProfilePathByUserIdHash(user_id_hash));
}
}  // namespace

namespace ash {

ChromeFeaturesServiceProvider::ChromeFeaturesServiceProvider(
    std::unique_ptr<base::FeatureList::Accessor> feature_list_accessor)
    : feature_list_accessor_(std::move(feature_list_accessor)) {}

ChromeFeaturesServiceProvider::~ChromeFeaturesServiceProvider() = default;

void ChromeFeaturesServiceProvider::Start(
    scoped_refptr<dbus::ExportedObject> exported_object) {
  exported_object->ExportMethod(
      chromeos::kChromeFeaturesServiceInterface,
      chromeos::kChromeFeaturesServiceIsFeatureEnabledMethod,
      base::BindRepeating(&ChromeFeaturesServiceProvider::IsFeatureEnabled,
                          weak_ptr_factory_.GetWeakPtr()),
      base::BindOnce(&ChromeFeaturesServiceProvider::OnExported,
                     weak_ptr_factory_.GetWeakPtr()));
  exported_object->ExportMethod(
      chromeos::kChromeFeaturesServiceInterface,
      chromeos::kChromeFeaturesServiceGetFeatureParamsMethod,
      base::BindRepeating(&ChromeFeaturesServiceProvider::GetFeatureParams,
                          weak_ptr_factory_.GetWeakPtr()),
      base::BindOnce(&ChromeFeaturesServiceProvider::OnExported,
                     weak_ptr_factory_.GetWeakPtr()));
  exported_object->ExportMethod(
      chromeos::kChromeFeaturesServiceInterface,
      chromeos::kChromeFeaturesServiceIsCrostiniEnabledMethod,
      base::BindRepeating(&ChromeFeaturesServiceProvider::IsCrostiniEnabled,
                          weak_ptr_factory_.GetWeakPtr()),
      base::BindOnce(&ChromeFeaturesServiceProvider::OnExported,
                     weak_ptr_factory_.GetWeakPtr()));
  exported_object->ExportMethod(
      chromeos::kChromeFeaturesServiceInterface,
      chromeos::kChromeFeaturesServiceIsPluginVmEnabledMethod,
      base::BindRepeating(&ChromeFeaturesServiceProvider::IsPluginVmEnabled,
                          weak_ptr_factory_.GetWeakPtr()),
      base::BindOnce(&ChromeFeaturesServiceProvider::OnExported,
                     weak_ptr_factory_.GetWeakPtr()));
  exported_object->ExportMethod(
      chromeos::kChromeFeaturesServiceInterface,
      chromeos::kChromeFeaturesServiceIsCryptohomeDistributedModelEnabledMethod,
      base::BindRepeating(
          &ChromeFeaturesServiceProvider::IsCryptohomeDistributedModelEnabled,
          weak_ptr_factory_.GetWeakPtr()),
      base::BindRepeating(&ChromeFeaturesServiceProvider::OnExported,
                          weak_ptr_factory_.GetWeakPtr()));
  exported_object->ExportMethod(
      chromeos::kChromeFeaturesServiceInterface,
      chromeos::kChromeFeaturesServiceIsCryptohomeUserDataAuthEnabledMethod,
      base::BindRepeating(
          &ChromeFeaturesServiceProvider::IsCryptohomeUserDataAuthEnabled,
          weak_ptr_factory_.GetWeakPtr()),
      base::BindRepeating(&ChromeFeaturesServiceProvider::OnExported,
                          weak_ptr_factory_.GetWeakPtr()));
  exported_object->ExportMethod(
      chromeos::kChromeFeaturesServiceInterface,
      chromeos::
          kChromeFeaturesServiceIsCryptohomeUserDataAuthKillswitchEnabledMethod,
      base::BindRepeating(&ChromeFeaturesServiceProvider::
                              IsCryptohomeUserDataAuthKillswitchEnabled,
                          weak_ptr_factory_.GetWeakPtr()),
      base::BindRepeating(&ChromeFeaturesServiceProvider::OnExported,
                          weak_ptr_factory_.GetWeakPtr()));
  exported_object->ExportMethod(
      chromeos::kChromeFeaturesServiceInterface,
      chromeos::kChromeFeaturesServiceIsVmManagementCliAllowedMethod,
      base::BindRepeating(
          &ChromeFeaturesServiceProvider::IsVmManagementCliAllowed,
          weak_ptr_factory_.GetWeakPtr()),
      base::BindOnce(&ChromeFeaturesServiceProvider::OnExported,
                     weak_ptr_factory_.GetWeakPtr()));
  exported_object->ExportMethod(
      chromeos::kChromeFeaturesServiceInterface,
      chromeos::kChromeFeaturesServiceIsPeripheralDataAccessEnabledMethod,
      base::BindRepeating(
          &ChromeFeaturesServiceProvider::IsPeripheralDataAccessEnabled,
          weak_ptr_factory_.GetWeakPtr()),
      base::BindRepeating(&ChromeFeaturesServiceProvider::OnExported,
                          weak_ptr_factory_.GetWeakPtr()));
  exported_object->ExportMethod(
      chromeos::kChromeFeaturesServiceInterface,
      chromeos::kChromeFeaturesServiceIsDNSProxyEnabledMethod,
      base::BindRepeating(&ChromeFeaturesServiceProvider::IsDnsProxyEnabled,
                          weak_ptr_factory_.GetWeakPtr()),
      base::BindRepeating(&ChromeFeaturesServiceProvider::OnExported,
                          weak_ptr_factory_.GetWeakPtr()));
}

void ChromeFeaturesServiceProvider::OnExported(
    const std::string& interface_name,
    const std::string& method_name,
    bool success) {
  if (!success) {
    LOG(ERROR) << "Failed to export " << interface_name << "." << method_name;
  }
}

void ChromeFeaturesServiceProvider::IsFeatureEnabled(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender response_sender) {
  static const base::Feature constexpr* kFeatureLookup[] = {
      &arc::kBootCompletedBroadcastFeature,
      &arc::kCustomTabsExperimentFeature,
      &arc::kFilePickerExperimentFeature,
      &arc::kNativeBridgeToggleFeature,
      &features::kSessionManagerLongKillTimeout,
      &features::kSessionManagerLivenessCheck,
      &features::kVmPerBootShaderCache,
  };

  dbus::MessageReader reader(method_call);
  std::string feature_name;
  if (!reader.PopString(&feature_name)) {
    LOG(ERROR) << "Failed to pop feature_name from incoming message.";
    std::move(response_sender)
        .Run(dbus::ErrorResponse::FromMethodCall(
            method_call, DBUS_ERROR_INVALID_ARGS,
            "Missing or invalid feature_name string arg."));
    return;
  }

  auto* const* it =
      std::find_if(std::begin(kFeatureLookup), std::end(kFeatureLookup),
                   [&feature_name](const base::Feature* feature) -> bool {
                     return feature_name == feature->name;
                   });
  if (it != std::end(kFeatureLookup)) {
    SendResponse(method_call, std::move(response_sender),
                 base::FeatureList::IsEnabled(**it));
    return;
  }
  // Not on our list. Potentially look up by name instead.
  // Only search for arbitrary trial names that begin with the appropriate
  // prefix, since looking up a feature by name will not be able to get the
  // default value associated with any `base::Feature` defined in the code
  // base.
  // Separately, a presubmit will enforce that no `base::Feature` definition
  // has a name starting with this prefix.
  // TODO(https://crbug.com/1263068): Add the aforementioned presubmit.
  base::FeatureList::OverrideState state =
      base::FeatureList::OVERRIDE_USE_DEFAULT;
  if (feature_name.find(kCrOSLateBootFeaturePrefix) == 0) {
    state = feature_list_accessor_->GetOverrideStateByFeatureName(feature_name);
  }
  if (state == base::FeatureList::OVERRIDE_USE_DEFAULT) {
    LOG(ERROR) << "Unexpected feature name '" << feature_name << "'";
    std::move(response_sender)
        .Run(dbus::ErrorResponse::FromMethodCall(
            method_call, DBUS_ERROR_INVALID_ARGS, "Unexpected feature name."));
    return;
  }
  SendResponse(method_call, std::move(response_sender),
               state == base::FeatureList::OVERRIDE_ENABLE_FEATURE);
}

void ChromeFeaturesServiceProvider::GetFeatureParams(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender response_sender) {
  dbus::MessageReader reader(method_call);
  dbus::MessageReader array_reader(nullptr);
  if (!reader.PopArray(&array_reader)) {
    LOG(ERROR) << "Failed to read array of feature names.";
    std::move(response_sender)
        .Run(dbus::ErrorResponse::FromMethodCall(
            method_call, DBUS_ERROR_INVALID_ARGS,
            "Could not pop string array of feature names"));
    return;
  }

  std::vector<std::string> features;
  std::map<std::string, std::map<std::string, std::string>> params_map;
  std::map<std::string, bool> enabled_map;
  while (array_reader.HasMoreData()) {
    std::string feature_name;

    if (!array_reader.PopString(&feature_name)) {
      LOG(ERROR) << "Failed to pop feature_name from array.";
      std::move(response_sender)
          .Run(dbus::ErrorResponse::FromMethodCall(
              method_call, DBUS_ERROR_INVALID_ARGS,
              "Missing or invalid feature_name string arg in array."));
      return;
    }

    if (feature_name.find(kCrOSLateBootFeaturePrefix) != 0) {
      LOG(ERROR) << "Unexpected feature name '" << feature_name << "'";
      std::move(response_sender)
          .Run(dbus::ErrorResponse::FromMethodCall(method_call,
                                                   DBUS_ERROR_INVALID_ARGS,
                                                   "Unexpected feature name."));
      return;
    }

    features.push_back(feature_name);

    base::FeatureList::OverrideState state =
        feature_list_accessor_->GetOverrideStateByFeatureName(feature_name);
    if (state == base::FeatureList::OVERRIDE_ENABLE_FEATURE) {
      enabled_map[feature_name] = true;
    } else if (state == base::FeatureList::OVERRIDE_DISABLE_FEATURE) {
      enabled_map[feature_name] = false;
    }
    // else leave it out of the map.

    std::map<std::string, std::string> per_feature_map;
    if (!feature_list_accessor_->GetParamsByFeatureName(feature_name,
                                                        &per_feature_map)) {
      LOG(ERROR) << "No trial found for '" << feature_name << "', skipping.";
      continue;
    }
    params_map[feature_name] = std::move(per_feature_map);
  }

  // Build response
  std::unique_ptr<dbus::Response> response =
      dbus::Response::FromMethodCall(method_call);
  dbus::MessageWriter writer(response.get());
  dbus::MessageWriter array_writer(nullptr);
  // A map from feature name to:
  // * two booleans:
  //   * Whether to use the override (or the default),
  //   * What the override state is (only valid if we should use the
  //     override value).
  // * Another map, from parameter name to value.
  writer.OpenArray("{s(bba{ss})}", &array_writer);
  for (const auto& feature_name : features) {
    dbus::MessageWriter feature_dict_writer(nullptr);
    array_writer.OpenDictEntry(&feature_dict_writer);
    feature_dict_writer.AppendString(feature_name);
    dbus::MessageWriter struct_writer(nullptr);
    feature_dict_writer.OpenStruct(&struct_writer);

    if (enabled_map.find(feature_name) != enabled_map.end()) {
      struct_writer.AppendBool(true);  // Use override
      struct_writer.AppendBool(enabled_map[feature_name]);
    } else {
      struct_writer.AppendBool(false);  // Ignore override
      struct_writer.AppendBool(false);  // Arbitrary choice
    }

    dbus::MessageWriter sub_array_writer(nullptr);
    struct_writer.OpenArray("{ss}", &sub_array_writer);
    if (params_map.find(feature_name) != params_map.end()) {
      const auto& submap = params_map[feature_name];
      for (const auto& [key, value] : submap) {
        dbus::MessageWriter dict_writer(nullptr);
        sub_array_writer.OpenDictEntry(&dict_writer);
        dict_writer.AppendString(key);
        dict_writer.AppendString(value);
        sub_array_writer.CloseContainer(&dict_writer);
      }
    }
    struct_writer.CloseContainer(&sub_array_writer);
    feature_dict_writer.CloseContainer(&struct_writer);
    array_writer.CloseContainer(&feature_dict_writer);
  }
  writer.CloseContainer(&array_writer);
  std::move(response_sender).Run(std::move(response));
}

void ChromeFeaturesServiceProvider::IsCrostiniEnabled(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender response_sender) {
  Profile* profile = GetSenderProfile(method_call, &response_sender);
  if (!profile)
    return;

  std::string reason;
  bool answer =
      crostini::CrostiniFeatures::Get()->IsAllowedNow(profile, &reason);
  SendResponse(method_call, std::move(response_sender), answer, reason);
}

void ChromeFeaturesServiceProvider::IsCryptohomeDistributedModelEnabled(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender response_sender) {
  SendResponse(
      method_call, std::move(response_sender),
      base::FeatureList::IsEnabled(::features::kCryptohomeDistributedModel));
}

void ChromeFeaturesServiceProvider::IsCryptohomeUserDataAuthEnabled(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender response_sender) {
  SendResponse(
      method_call, std::move(response_sender),
      base::FeatureList::IsEnabled(::features::kCryptohomeUserDataAuth));
}

void ChromeFeaturesServiceProvider::IsCryptohomeUserDataAuthKillswitchEnabled(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender response_sender) {
  SendResponse(method_call, std::move(response_sender),
               base::FeatureList::IsEnabled(
                   ::features::kCryptohomeUserDataAuthKillswitch));
}

void ChromeFeaturesServiceProvider::IsPluginVmEnabled(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender response_sender) {
  Profile* profile = GetSenderProfile(method_call, &response_sender);
  if (!profile)
    return;

  std::string reason;
  bool answer = plugin_vm::PluginVmFeatures::Get()->IsAllowed(profile, &reason);
  SendResponse(method_call, std::move(response_sender), answer, reason);
}

void ChromeFeaturesServiceProvider::IsVmManagementCliAllowed(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender response_sender) {
  Profile* profile = GetSenderProfile(method_call, &response_sender);
  if (!profile)
    return;

  SendResponse(method_call, std::move(response_sender),
               profile->GetPrefs()->GetBoolean(
                   crostini::prefs::kVmManagementCliAllowedByPolicy));
}

void ChromeFeaturesServiceProvider::IsPeripheralDataAccessEnabled(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender response_sender) {
  // TODO(1242686): Add end-to-end tests for this D-Bus signal.

  bool peripheral_data_access_enabled = false;
  // Enterprise managed devices use the local state pref.
  if (InstallAttributes::Get()->IsEnterpriseManaged()) {
    peripheral_data_access_enabled =
        g_browser_process->local_state()->GetBoolean(
            prefs::kLocalStateDevicePeripheralDataAccessEnabled);
  } else {
    // Consumer devices use the CrosSetting pref.
    CrosSettings::Get()->GetBoolean(kDevicePeripheralDataAccessEnabled,
                                    &peripheral_data_access_enabled);
  }
  SendResponse(method_call, std::move(response_sender),
               peripheral_data_access_enabled);
}

void ChromeFeaturesServiceProvider::IsDnsProxyEnabled(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender response_sender) {
  SendResponse(method_call, std::move(response_sender),
               base::FeatureList::IsEnabled(features::kEnableDnsProxy));
}

}  // namespace ash


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<meta name="collection" content="api">

<TITLE>
Pageable (Java 2 Platform SE 5.0)
</TITLE>

<META NAME="keywords" CONTENT="java.awt.print.Pageable interface">
<META NAME="keywords" CONTENT="UNKNOWN_NUMBER_OF_PAGES">
<META NAME="keywords" CONTENT="getNumberOfPages()">
<META NAME="keywords" CONTENT="getPageFormat()">
<META NAME="keywords" CONTENT="getPrintable()">

<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">

      Overview
      Package
    Class
      Use
      Tree
      Deprecated
      Index
      Help

JavaTM 2 Platform
Standard Ed. 5.0

 PREV CLASS
 NEXT CLASS

  FRAMES
 NO FRAMES

  All Classes

  SUMMARY: NESTED | FIELD | CONSTR | METHOD

DETAIL: FIELD | CONSTR | METHOD

java.awt.print

Interface Pageable

All Known Implementing Classes:
Book

public interface Pageable

The Pageable implementation represents a set of
 pages to be printed. The Pageable object returns
 the total number of pages in the set as well as the
 PageFormat and Printable for a specified page.

See Also:
PageFormat,
Printable

Field Summary

static int
UNKNOWN_NUMBER_OF_PAGES

          This constant is returned from the
 getNumberOfPages
 method if a Pageable implementation does not know
 the number of pages in its set.

Method Summary

 int
getNumberOfPages()

          Returns the number of pages in the set.

 PageFormat
getPageFormat(int pageIndex)

          Returns the PageFormat of the page specified by
 pageIndex.

 Printable
getPrintable(int pageIndex)

          Returns the Printable instance responsible for
 rendering the page specified by pageIndex.

Field Detail

UNKNOWN_NUMBER_OF_PAGES

static final int UNKNOWN_NUMBER_OF_PAGES

This constant is returned from the
 getNumberOfPages
 method if a Pageable implementation does not know
 the number of pages in its set.

See Also:
Constant Field Values

Method Detail

getNumberOfPages

int getNumberOfPages()

Returns the number of pages in the set.
 To enable advanced printing features,
 it is recommended that Pageable
 implementations return the true number of pages
 rather than the
 UNKNOWN_NUMBER_OF_PAGES constant.

Returns:
the number of pages in this Pageable.

getPageFormat

PageFormat getPageFormat(int pageIndex)
                         throws IndexOutOfBoundsException

Returns the PageFormat of the page specified by
 pageIndex.

Parameters:
pageIndex - the zero based index of the page whose
            PageFormat is being requested

Returns:
the PageFormat describing the size and
                orientation.

Throws:

IndexOutOfBoundsException - if
          the Pageable does not contain the requested
                page.

getPrintable

Printable getPrintable(int pageIndex)
                       throws IndexOutOfBoundsException

Returns the Printable instance responsible for
 rendering the page specified by pageIndex.

Parameters:
pageIndex - the zero based index of the page whose
            Printable is being requested

Returns:
the Printable that renders the page.

Throws:

IndexOutOfBoundsException - if
            the Pageable does not contain the requested
                  page.

      Overview
      Package
    Class
      Use
      Tree
      Deprecated
      Index
      Help

JavaTM 2 Platform
Standard Ed. 5.0

 PREV CLASS
 NEXT CLASS

  FRAMES
 NO FRAMES

  All Classes

  SUMMARY: NESTED | FIELD | CONSTR | METHOD

DETAIL: FIELD | CONSTR | METHOD

Submit a bug or feature
For further API reference and developer documentation, see Java 2 SDK SE Developer Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 2004, 2010 Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Also see the documentation redistribution policy.

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE html>

    <title>One-to-One File Sharing using RTCMultiConnection ® Muaz Khan</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
    <meta name="author" content="Muaz Khan">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <link rel="stylesheet" href="//cdn.webrtc-experiment.com/style.css">

One-to-One File Sharing using RTCMultiConnection

            HOME
             ©
            Muaz Khan .
            @WebRTCWeb .
            Github .
            Latest issues .
            What's New?

Open Data Channel

            <input type="text" id="channel" value="channel" style="font-size: 1.1em; text-align: right; width: 8em;" title="channel name - use your own channel name">
            <button id="init-RTCMultiConnection">Open</button>

or join:

            <button id="join-RTCMultiConnection">Join</button>

Share Files

                    <input type="file" id="file" disabled>

            RTCMultiConnection Documentation!

Feedback

                <textarea id="message" style="border: 1px solid rgb(189, 189, 189); height: 8em; margin: .2em; outline: none; resize: vertical; width: 98%;" placeholder="Have any message? Suggestions or something went wrong?"></textarea>

            <button id="send-message" style="font-size: 1em;">Send Message</button>

        WebRTC Experiments! and
        RTCMultiConnection.js ©
        Muaz Khan:
        @WebRTCWeb


text:
<!DOCTYPE html>

  <meta charset="utf-8">
  <base data-ice="baseUrl">
  <title data-ice="title">API Document</title>
  <link type="text/css" rel="stylesheet" href="css/style.css">
  <link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">

  Home

  Reference
  Source

  Repository

    <input class="search-input">

actions
FaddSiteVersion

FaddSiteVersionSuccess

FdeleteSiteVersion

FdeleteSiteVersionSuccess

FloadModes

FloadModesSuccess

FloadSiteVersions

FloadSiteVersionsSuccess

FloadVersions

FloadVersionsSuccess

FupdateSiteVersion

FupdateSiteVersionSuccess

FloadFiles

FloadFilesSuccess

FuploadFiles

FuploadFilesSuccess

api
CModeApi

CSiteVersionApi

CUploadApi

CVersionApi

components
CApp

CHomePage

FNotFoundPage

constants
VCREATE_SITEVERSIONS

VDELETE_SITEVERSIONS

VLOAD_FILES_SUCCESS

VLOAD_MODES

VLOAD_SITEVERSIONS

VLOAD_VERSIONS

VUPDATE_SITEVERSIONS

VUPLOAD_FILES_SUCCESS

reducers
Fmodes

FuploadFiles

Fversions

VrootReducer

store
VconfigureStore

// To run the app
// Open the terminal
// set the path
// example: username $ cd/path/
// Next $ yarn install
// Next $ npm start

// To run the test
// Type npm test and enter

  Generated by ESDoc(0.5.2)


text:
from oslo_config import cfg
from oslo_log import log as logging
from webob import exc

from cinder.api.contrib import resource_common_manage
from cinder.api import extensions
from cinder.api.openstack import wsgi
from cinder.api.views import manageable_snapshots as list_manageable_view
from cinder.api.views import snapshots as snapshot_views
from cinder import exception
from cinder.i18n import _
from cinder import volume as cinder_volume

LOG = logging.getLogger(__name__)
CONF = cfg.CONF
authorize_manage = extensions.extension_authorizer('snapshot',
                                                   'snapshot_manage')
authorize_list_manageable = extensions.extension_authorizer('snapshot',
                                                            'list_manageable')

class SnapshotManageController(wsgi.Controller):
    """The /os-snapshot-manage controller for the OpenStack API."""

    _view_builder_class = snapshot_views.ViewBuilder

    def __init__(self, *args, **kwargs):
        super(SnapshotManageController, self).__init__(*args, **kwargs)
        self.volume_api = cinder_volume.API()
        self._list_manageable_view = list_manageable_view.ViewBuilder()

    @wsgi.response(202)
    def create(self, req, body):
        """Instruct Cinder to manage a storage snapshot object.

        Manages an existing backend storage snapshot object (e.g. a Linux
        logical volume or a SAN disk) by creating the Cinder objects required
        to manage it, and possibly renaming the backend storage snapshot object
        (driver dependent).

        From an API perspective, this operation behaves very much like a
        snapshot creation operation.

        Required HTTP Body:

        .. code-block:: json

         {
           "snapshot":
           {
             "volume_id": <Cinder volume already exists in volume backend>,
             "ref":  <Driver-specific reference to the existing storage object>
           }
         }

        See the appropriate Cinder drivers' implementations of the
        manage_snapshot method to find out the accepted format of 'ref'.
        For example,in LVM driver, it will be the logic volume name of snapshot
        which you want to manage.

        This API call will return with an error if any of the above elements
        are missing from the request, or if the 'volume_id' element refers to
        a cinder volume that could not be found.

        The snapshot will later enter the error state if it is discovered that
        'ref' is bad.

        Optional elements to 'snapshot' are::

         name           A name for the new snapshot.
         description    A description for the new snapshot.
         metadata       Key/value pairs to be associated with the new snapshot.

        """
        context = req.environ['cinder.context']
        authorize_manage(context)

        if not self.is_valid_body(body, 'snapshot'):
            msg = _("Missing required element snapshot in request body.")
            raise exc.HTTPBadRequest(explanation=msg)

        snapshot = body['snapshot']

        # Check that the required keys are present, return an error if they
        # are not.
        required_keys = ('ref', 'volume_id')
        missing_keys = set(required_keys) - set(snapshot.keys())

        if missing_keys:
            msg = _("The following elements are required: "
                    "%s") % ', '.join(missing_keys)
            raise exc.HTTPBadRequest(explanation=msg)

        # Check whether volume exists
        volume_id = snapshot['volume_id']
        try:
            volume = self.volume_api.get(context, volume_id)
        except exception.VolumeNotFound:
            msg = _("Volume: %s could not be found.") % volume_id
            raise exc.HTTPNotFound(explanation=msg)

        LOG.debug('Manage snapshot request body: %s', body)

        snapshot_parameters = {}

        snapshot_parameters['metadata'] = snapshot.get('metadata', None)
        snapshot_parameters['description'] = snapshot.get('description', None)
        snapshot_parameters['name'] = snapshot.get('name')

        try:
            new_snapshot = self.volume_api.manage_existing_snapshot(
                context,
                snapshot['ref'],
                volume,
                **snapshot_parameters)
        except exception.ServiceNotFound:
            msg = _("Service %s not found.") % CONF.volume_topic
            raise exc.HTTPNotFound(explanation=msg)

        return self._view_builder.detail(req, new_snapshot)

    @wsgi.extends
    def index(self, req):
        """Returns a summary list of snapshots available to manage."""
        context = req.environ['cinder.context']
        authorize_list_manageable(context)
        return resource_common_manage.get_manageable_resources(
            req, False, self.volume_api.get_manageable_snapshots,
            self._list_manageable_view)

    @wsgi.extends
    def detail(self, req):
        """Returns a detailed list of snapshots available to manage."""
        context = req.environ['cinder.context']
        authorize_list_manageable(context)
        return resource_common_manage.get_manageable_resources(
            req, True, self.volume_api.get_manageable_snapshots,
            self._list_manageable_view)

class Snapshot_manage(extensions.ExtensionDescriptor):
    """Allows existing backend storage to be 'managed' by Cinder."""

    name = 'SnapshotManage'
    alias = 'os-snapshot-manage'
    updated = '2014-12-31T00:00:00+00:00'

    def get_resources(self):
        controller = SnapshotManageController()
        return [extensions.ResourceExtension(Snapshot_manage.alias,
                                             controller,
                                             collection_actions=
                                             {'detail': 'GET'})]


text:
/**
 * dimension display names
 *
 * @param config
 * @param d
 * @returns {*}
 */
const dimensionLabels = config => d =>
  config.dimensions[d].title ? config.dimensions[d].title : d;

export default dimensionLabels;