<commit_before>/*
 * Software License Agreement (BSD License)
 *
 * Copyright (c) 2014-, Open Perception, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided
 * with the distribution.
 * * Neither the name of the copyright holder(s) nor the names of its
 * contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * Author: Matteo Munaro [matteo.munaro@dei.unipd.it]
 *         Filippo Basso [filippo.basso@dei.unipd.it]
 *
 */

#include <ros/ros.h>
#include <ros/package.h>
#include <fstream>
#include <string.h>

int
main(int argc, char ** argv)
{
  ros::init(argc, argv, "calibration_initializer");
  ros::NodeHandle nh("~");

  // Read some parameters from launch file:
  int num_sensors;
  nh.param("num_sensors", num_sensors, 1);
  bool calibration_with_serials;
  nh.param("calibration_with_serials", calibration_with_serials, false);
  int rows;
  nh.param("rows", rows, 6);
  int cols;
  nh.param("cols", cols, 5);
  double cell_width;
  nh.param("cell_width", cell_width, 0.12);
  double cell_height;
  nh.param("cell_height", cell_height, 0.12);
  std::string driver_name;
  nh.param("driver", driver_name, std::string("openni"));

  // Read ID of sensors:
  std::vector<std::string> sensor_id_vector;
  for (unsigned int i = 0; i < num_sensors; i++)
  {
    std::stringstream ss;
    ss << "sensor" << i << "_id";
    std::string sensor_id;
    nh.param(ss.str(), sensor_id, std::string("./"));
    sensor_id_vector.push_back(sensor_id);
  }

  // Write launch file to be used for extrinsic calibration of the sensor network:
  std::string file_name = ros::package::getPath("opt_calibration") + "/launch/opt_calibration_master.launch";
  std::ofstream launch_file;
  launch_file.open(file_name.c_str());

  if (launch_file.is_open())
  {
    launch_file << "<launch>" << std::endl << std::endl;

    // Network parameters:
    launch_file << "  <!-- Network parameters -->" << std::endl
                << "  <arg name=\"num_sensors\" value=\"" << num_sensors << "\" />" << std::endl;

    for (unsigned int i = 0; i < num_sensors; i++)
    {
      if (!std::strcmp(sensor_id_vector[i].substr(0,1).c_str(), "1"))    // if SwissRanger
      {
        std::string sensor_name = sensor_id_vector[i];
        replace(sensor_name.begin(), sensor_name.end(), '.', '_');
        sensor_name = "SR_" + sensor_name;
        launch_file << "  <arg name=\"sensor" << i << "_id\" value=\"" << sensor_name << "\" />" << std::endl;
      }
      else
      {
        launch_file << "  <arg name=\"sensor" << i << "_id\" value=\"" << sensor_id_vector[i] << "\" />" << std::endl;
      }
      launch_file << "  <arg name=\"sensor" << i << "_name\" default=\"$(arg sensor" << i << "_id)\" />" << std::endl;
    }

    // Checkerboard parameters:
    launch_file << "  <!-- Checkerboard parameters -->" << std::endl
        << "  <arg name=\"rows\" default=\"" << rows << "\" />" << std::endl
        << "  <arg name=\"cols\" default=\"" << cols << "\" />" << std::endl
        << "  <arg name=\"cell_width\" default=\"" << cell_width << "\" />" << std::endl
        << "  <arg name=\"cell_height\" default=\"" << cell_height << "\" />" << std::endl << std::endl;

    // RViz and calibration node:
    launch_file << "  <!-- Opening Rviz for visualization-->" << std::endl
        << "  <node name=\"rviz\" pkg=\"rviz\" type=\"rviz\" args=\"-d $(find opt_calibration)/conf/opt_calibration.rviz\"/>" << std::endl << std::endl
        << "  <!-- Launching calibration -->" << std::endl
        << "  <node pkg=\"opt_calibration\" type=\"opt_calibration\" name=\"opt_calibration\" output=\"screen\">" << std::endl
        << "    <param name=\"num_sensors\" value=\"$(arg num_sensors)\" /> " << std::endl
        << "    <param name=\"rows\" value=\"$(arg rows)\" />" << std::endl
        << "    <param name=\"cols\" value=\"$(arg cols)\" />" << std::endl
        << "    <param name=\"cell_width\" value=\"$(arg cell_width)\" />" << std::endl
        << "    <param name=\"cell_height\" value=\"$(arg cell_height)\" />" << std::endl << std::endl
        << "    <param name=\"base_sensor\" value=\"$(arg base_sensor)\" />" << std::endl << std::endl;

    if (calibration_with_serials)
      launch_file << "    <param name=\"calibration_with_serials\" value=\"true\" />" << std::endl << std::endl;

    // Parameters and remapping for every sensor:
    for (unsigned int i = 0; i < num_sensors; i++)
    {
      launch_file << "    <param name=\"sensor_" << i << "/name\" value=\"/$(arg sensor" << i << "_name)\" />" << std::endl;

      if (!std::strcmp(sensor_id_vector[i].substr(0,1).c_str(), "1"))    // if SwissRanger (sensor_id is an IP address)
      {
        launch_file << "    <param name=\"sensor_" << i << "/type\" value=\"pinhole_rgb\" />" << std::endl;
        launch_file << "    <remap from=\"~sensor_" << i << "/image\" to=\"/$(arg sensor" << i << "_name)/intensity/image_resized\" />" << std::endl;
        launch_file << "    <remap from=\"~sensor_" << i << "/camera_info\" to=\"/$(arg sensor" << i << "_name)/intensity/camera_info\" />" << std::endl << std::endl;
      }
      else                                                              // if Kinect
      {
        launch_file << "    <param name=\"sensor_" << i << "/type\" value=\"pinhole_rgb\" />" << std::endl;
        launch_file << "    <remap from=\"~sensor_" << i << "/image\" to=\"/$(arg sensor" << i << "_name)/rgb/image_rect_color\" />" << std::endl;
        launch_file << "    <remap from=\"~sensor_" << i << "/camera_info\" to=\"/$(arg sensor" << i << "_name)/rgb/camera_info\" />" << std::endl << std::endl;
      }
    }

    launch_file << "  </node>" << std::endl << std::endl;

    launch_file << "</launch>" << std::endl;
  }
  launch_file.close();
  ROS_INFO_STREAM(file_name << " created!");

  // Write a launch file for every sensor:
  for (unsigned int i = 0; i < num_sensors; i++)
  {
    std::string sensor_name = sensor_id_vector[i];
    if (!std::strcmp(sensor_id_vector[i].substr(0,1).c_str(), "1"))    // if SwissRanger (sensor_id is an IP address)
    {
      replace(sensor_name.begin(), sensor_name.end(), '.', '_');
      sensor_name = "SR_" + sensor_name;
    }

    file_name = ros::package::getPath("opt_calibration") + "/launch/sensor_" + sensor_name + ".launch";
    std::ofstream launch_file;
    launch_file.open(file_name.c_str());

    if (launch_file.is_open())
    {
      launch_file << "<launch>" << std::endl << std::endl;

      launch_file << "  <!-- sensor parameters -->" << std::endl
          << "  <arg name=\"sensor_id\" value=\"" << sensor_name << "\" />" << std::endl
          << "  <arg name=\"sensor_name\" default=\"$(arg sensor_id)\" />" << std::endl << std::endl;

      if (!std::strcmp(sensor_id_vector[i].substr(0,1).c_str(), "1"))    // if SwissRanger (sensor_id is an IP address)
      {
        launch_file << "  <!-- Launch sensor -->" << std::endl
            << "  <include file=\"$(find swissranger_camera)/launch/sr_eth.launch\">" << std::endl
            << "    <arg name=\"camera_id\" value=\"$(arg sensor_id)\" />" << std::endl
            << "    <arg name=\"device_ip\" value=\"" << sensor_id_vector[i] << "\" />" << std::endl
            << "  </include>" << std::endl << std::endl
            << "  <include file=\"$(find swissranger_camera)/launch/publisher_for_calibration.launch\">" << std::endl
            << "    <arg name=\"camera_id\" value=\"$(arg sensor_id)\" />" << std::endl
            << "  </include>" << std::endl << std::endl;
      }
      else                                                               // if Kinect
      {
        launch_file << "  <!-- Launch sensor -->" << std::endl
            << "  <include file=\"$(find detection)/launch/" << driver_name << ".launch\">" << std::endl;

        // If serial numbers can be used to identify sensors, they are added to the launch file:
        if (calibration_with_serials)
          launch_file << "    <arg name=\"device_id\" value=\"$(arg sensor_id)\" />" << std::endl;

        launch_file << "    <arg name=\"camera\" value=\"$(arg sensor_name)\" />" << std::endl
            << "  </include>" << std::endl << std::endl;

        launch_file << "  <!-- Publish a further transform -->" << std::endl
            << "  <node pkg=\"tf\" type=\"static_transform_publisher\" name=\"$(arg sensor_name)_broadcaster\" args=\"-0.045 0 0 1.57079 -1.57079 0 /$(arg sensor_name) /$(arg sensor_name)_link  100\" />" << std::endl << std::endl;
      }
      launch_file << "</launch>" << std::endl;
    }
    launch_file.close();
    ROS_INFO_STREAM(file_name << " created!");
  }

  return 0;
}
<commit_msg>Bugfix. Removed base_sensor param from opt_calibration/launch/opt_calibration_master.launch creation.<commit_after>/*
 * Software License Agreement (BSD License)
 *
 * Copyright (c) 2014-, Open Perception, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided
 * with the distribution.
 * * Neither the name of the copyright holder(s) nor the names of its
 * contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * Author: Matteo Munaro [matteo.munaro@dei.unipd.it]
 *         Filippo Basso [filippo.basso@dei.unipd.it]
 *
 */

#include <ros/ros.h>
#include <ros/package.h>
#include <fstream>
#include <string.h>

int
main(int argc, char ** argv)
{
  ros::init(argc, argv, "calibration_initializer");
  ros::NodeHandle nh("~");

  // Read some parameters from launch file:
  int num_sensors;
  nh.param("num_sensors", num_sensors, 1);
  bool calibration_with_serials;
  nh.param("calibration_with_serials", calibration_with_serials, false);
  int rows;
  nh.param("rows", rows, 6);
  int cols;
  nh.param("cols", cols, 5);
  double cell_width;
  nh.param("cell_width", cell_width, 0.12);
  double cell_height;
  nh.param("cell_height", cell_height, 0.12);
  std::string driver_name;
  nh.param("driver", driver_name, std::string("openni"));

  // Read ID of sensors:
  std::vector<std::string> sensor_id_vector;
  for (unsigned int i = 0; i < num_sensors; i++)
  {
    std::stringstream ss;
    ss << "sensor" << i << "_id";
    std::string sensor_id;
    nh.param(ss.str(), sensor_id, std::string("./"));
    sensor_id_vector.push_back(sensor_id);
  }

  // Write launch file to be used for extrinsic calibration of the sensor network:
  std::string file_name = ros::package::getPath("opt_calibration") + "/launch/opt_calibration_master.launch";
  std::ofstream launch_file;
  launch_file.open(file_name.c_str());

  if (launch_file.is_open())
  {
    launch_file << "<launch>" << std::endl << std::endl;

    // Network parameters:
    launch_file << "  <!-- Network parameters -->" << std::endl
                << "  <arg name=\"num_sensors\" value=\"" << num_sensors << "\" />" << std::endl;

    for (unsigned int i = 0; i < num_sensors; i++)
    {
      if (!std::strcmp(sensor_id_vector[i].substr(0,1).c_str(), "1"))    // if SwissRanger
      {
        std::string sensor_name = sensor_id_vector[i];
        replace(sensor_name.begin(), sensor_name.end(), '.', '_');
        sensor_name = "SR_" + sensor_name;
        launch_file << "  <arg name=\"sensor" << i << "_id\" value=\"" << sensor_name << "\" />" << std::endl;
      }
      else
      {
        launch_file << "  <arg name=\"sensor" << i << "_id\" value=\"" << sensor_id_vector[i] << "\" />" << std::endl;
      }
      launch_file << "  <arg name=\"sensor" << i << "_name\" default=\"$(arg sensor" << i << "_id)\" />" << std::endl;
    }

    // Checkerboard parameters:
    launch_file << "  <!-- Checkerboard parameters -->" << std::endl
        << "  <arg name=\"rows\" default=\"" << rows << "\" />" << std::endl
        << "  <arg name=\"cols\" default=\"" << cols << "\" />" << std::endl
        << "  <arg name=\"cell_width\" default=\"" << cell_width << "\" />" << std::endl
        << "  <arg name=\"cell_height\" default=\"" << cell_height << "\" />" << std::endl << std::endl;

    // RViz and calibration node:
    launch_file << "  <!-- Opening Rviz for visualization-->" << std::endl
        << "  <node name=\"rviz\" pkg=\"rviz\" type=\"rviz\" args=\"-d $(find opt_calibration)/conf/opt_calibration.rviz\"/>" << std::endl << std::endl
        << "  <!-- Launching calibration -->" << std::endl
        << "  <node pkg=\"opt_calibration\" type=\"opt_calibration\" name=\"opt_calibration\" output=\"screen\">" << std::endl
        << "    <param name=\"num_sensors\" value=\"$(arg num_sensors)\" /> " << std::endl
        << "    <param name=\"rows\" value=\"$(arg rows)\" />" << std::endl
        << "    <param name=\"cols\" value=\"$(arg cols)\" />" << std::endl
        << "    <param name=\"cell_width\" value=\"$(arg cell_width)\" />" << std::endl
        << "    <param name=\"cell_height\" value=\"$(arg cell_height)\" />" << std::endl << std::endl;

    if (calibration_with_serials)
      launch_file << "    <param name=\"calibration_with_serials\" value=\"true\" />" << std::endl << std::endl;

    // Parameters and remapping for every sensor:
    for (unsigned int i = 0; i < num_sensors; i++)
    {
      launch_file << "    <param name=\"sensor_" << i << "/name\" value=\"/$(arg sensor" << i << "_name)\" />" << std::endl;

      if (!std::strcmp(sensor_id_vector[i].substr(0,1).c_str(), "1"))    // if SwissRanger (sensor_id is an IP address)
      {
        launch_file << "    <param name=\"sensor_" << i << "/type\" value=\"pinhole_rgb\" />" << std::endl;
        launch_file << "    <remap from=\"~sensor_" << i << "/image\" to=\"/$(arg sensor" << i << "_name)/intensity/image_resized\" />" << std::endl;
        launch_file << "    <remap from=\"~sensor_" << i << "/camera_info\" to=\"/$(arg sensor" << i << "_name)/intensity/camera_info\" />" << std::endl << std::endl;
      }
      else                                                              // if Kinect
      {
        launch_file << "    <param name=\"sensor_" << i << "/type\" value=\"pinhole_rgb\" />" << std::endl;
        launch_file << "    <remap from=\"~sensor_" << i << "/image\" to=\"/$(arg sensor" << i << "_name)/rgb/image_rect_color\" />" << std::endl;
        launch_file << "    <remap from=\"~sensor_" << i << "/camera_info\" to=\"/$(arg sensor" << i << "_name)/rgb/camera_info\" />" << std::endl << std::endl;
      }
    }

    launch_file << "  </node>" << std::endl << std::endl;

    launch_file << "</launch>" << std::endl;
  }
  launch_file.close();
  ROS_INFO_STREAM(file_name << " created!");

  // Write a launch file for every sensor:
  for (unsigned int i = 0; i < num_sensors; i++)
  {
    std::string sensor_name = sensor_id_vector[i];
    if (!std::strcmp(sensor_id_vector[i].substr(0,1).c_str(), "1"))    // if SwissRanger (sensor_id is an IP address)
    {
      replace(sensor_name.begin(), sensor_name.end(), '.', '_');
      sensor_name = "SR_" + sensor_name;
    }

    file_name = ros::package::getPath("opt_calibration") + "/launch/sensor_" + sensor_name + ".launch";
    std::ofstream launch_file;
    launch_file.open(file_name.c_str());

    if (launch_file.is_open())
    {
      launch_file << "<launch>" << std::endl << std::endl;

      launch_file << "  <!-- sensor parameters -->" << std::endl
          << "  <arg name=\"sensor_id\" value=\"" << sensor_name << "\" />" << std::endl
          << "  <arg name=\"sensor_name\" default=\"$(arg sensor_id)\" />" << std::endl << std::endl;

      if (!std::strcmp(sensor_id_vector[i].substr(0,1).c_str(), "1"))    // if SwissRanger (sensor_id is an IP address)
      {
        launch_file << "  <!-- Launch sensor -->" << std::endl
            << "  <include file=\"$(find swissranger_camera)/launch/sr_eth.launch\">" << std::endl
            << "    <arg name=\"camera_id\" value=\"$(arg sensor_id)\" />" << std::endl
            << "    <arg name=\"device_ip\" value=\"" << sensor_id_vector[i] << "\" />" << std::endl
            << "  </include>" << std::endl << std::endl
            << "  <include file=\"$(find swissranger_camera)/launch/publisher_for_calibration.launch\">" << std::endl
            << "    <arg name=\"camera_id\" value=\"$(arg sensor_id)\" />" << std::endl
            << "  </include>" << std::endl << std::endl;
      }
      else                                                               // if Kinect
      {
        launch_file << "  <!-- Launch sensor -->" << std::endl
            << "  <include file=\"$(find detection)/launch/" << driver_name << ".launch\">" << std::endl;

        // If serial numbers can be used to identify sensors, they are added to the launch file:
        if (calibration_with_serials)
          launch_file << "    <arg name=\"device_id\" value=\"$(arg sensor_id)\" />" << std::endl;

        launch_file << "    <arg name=\"camera\" value=\"$(arg sensor_name)\" />" << std::endl
            << "  </include>" << std::endl << std::endl;

        launch_file << "  <!-- Publish a further transform -->" << std::endl
            << "  <node pkg=\"tf\" type=\"static_transform_publisher\" name=\"$(arg sensor_name)_broadcaster\" args=\"-0.045 0 0 1.57079 -1.57079 0 /$(arg sensor_name) /$(arg sensor_name)_link  100\" />" << std::endl << std::endl;
      }
      launch_file << "</launch>" << std::endl;
    }
    launch_file.close();
    ROS_INFO_STREAM(file_name << " created!");
  }

  return 0;
}
<|endoftext|>


<commit_before>/*
  This C++ file contains unit tests for the push server.
 */

#include <algorithm>
#include <exception>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

#include <cpprest/http_client.h>
#include <cpprest/json.h>

#include <pplx/pplxtasks.h>

#include <UnitTest++/UnitTest++.h>
#include <UnitTest++/TestReporterStdout.h>

#include "tester-utils.h"

using std::cout;
using std::cerr;
using std::endl;
using std::make_pair;
using std::pair;
using std::string;
using std::vector;

using web::http::http_headers;
using web::http::http_request;
using web::http::http_response;
using web::http::method;
using web::http::methods;
using web::http::status_code;
using web::http::status_codes;
using web::http::uri_builder;

using web::http::client::http_client;

using web::json::object;
using web::json::value;

using namespace rest_operations;

class PushFixture {
public:

  // User Entity 0
  static constexpr const char* userid_0 {"user_0"};
  static constexpr const char* row_0 {"0,Ben"};

  static constexpr const char* friends_val_0 {"1,Ben|2,Ben"};
  static constexpr const char* status_val_0 {"A status update which is 47 characters long by 0"};
  static constexpr const char* status_update_0 {"A status update which is 52 characters long by 0"};

  // User Entity 1
  static constexpr const char* userid_1 {"user_1"};
  static constexpr const char* row_1 {"1,Ben"};

  static constexpr const char* friends_val_1 {"0,Ben|2,Ben"};
  static constexpr const char* status_val_1 {"A status update which is 47 characters long by 1"};
  static constexpr const char* status_update_1 {"A status update which is 52 characters long by 1"};

  // User Entity 2
  static constexpr const char* userid_2 {"user_2"};
  static constexpr const char* row_2 {"2,Ben"};

  static constexpr const char* friends_val_2 {"0,Ben|1,Ben"};
  static constexpr const char* status_val_2 {"A status update which is 47 characters long by 2"};
  static constexpr const char* status_update_2 {"A status update which is 52 characters long by 2"};

  // Constants for initializing tests
  // Represents a user's credentials
  static constexpr const char* addr {"http://localhost:34568/"};
  static constexpr const char* auth_addr {"http://localhost:34570/"};
  static constexpr const char* user_addr {"http://localhost:34572/"};
  static constexpr const char* user_pwd {"user"};
  static constexpr const char* auth_table {"AuthTable"};
  static constexpr const char* auth_table_partition {"Userid"};
  static constexpr const char* auth_pwd_prop {"Password"};

  // Represents the user's entry including friends and status
  static constexpr const char* table {"DataTable"};
  static constexpr const char* partition {"USA"};
  static constexpr const char* friends {"Friends"};
  static constexpr const char* status {"Status"};
  static constexpr const char* updates {"Updates"};
  static constexpr const char* updates_val {""};

public:
  PushFixture() {

    // Create table DataTable and add a test entry
    {
      int make_result {create_table(addr, table)};
      cerr << "create result " << make_result << endl;
      if (make_result != status_codes::Created && make_result != status_codes::Accepted) {
        throw std::exception();
      }
      //Create entity 0 in DataTable
      int put_result {put_entity (
        addr,
        table,
        partition,
        row_0,
        vector<pair<string,value>>{make_pair(string(friends),value::string(friends_val_0)),
          make_pair(string(status),value::string(status_val_0)),
          make_pair(string(updates),value::string(updates_val))
        }
      )};
      cerr << "data table insertion result " << put_result << endl;
      if (put_result != status_codes::OK) {
        throw std::exception();
      }
      // Create entity 1 in DataTable
      put_result = put_entity (
        addr,
        table,
        partition,
        row_1,
        vector<pair<string,value>>{make_pair(string(friends),value::string(friends_val_1)),
          make_pair(string(status),value::string(status_val_1)),
          make_pair(string(updates),value::string(updates_val))
      )};
      cerr << "data table insertion result " << put_result << endl;
      if (put_result != status_codes::OK) {
        throw std::exception();
      }
      // Create entity 2 in DataTable
      put_result = put_entity (
        addr,
        table,
        partition,
        row_2,
        vector<pair<string,value>>{make_pair(string(friends),value::string(friends_val_2)),
          make_pair(string(status),value::string(status_val_2)),
          make_pair(string(updates),value::string(updates_val))
      )};
      cerr << "data table insertion result " << put_result << endl;
      if (put_result != status_codes::OK) {
        throw std::exception();
      }
    }

    // Create table AuthTable and add an entry 0 authenticating the test case
    // in DataTable
    {
      int make_result {create_table(addr, auth_table)};
      cerr << "create result " << make_result << endl;
      if (make_result != status_codes::Created && make_result != status_codes::Accepted) {
        throw std::exception();
      }

      vector<pair<string, value>> properties;
      properties.push_back( make_pair(string(auth_pwd_prop), value::string(user_pwd)) );
      properties.push_back( make_pair("DataPartition", value::string(PushFixture::partition)) );
      properties.push_back( make_pair("DataRow", value::string(PushFixture::row_0)) );

      assert(properties.size() == 3);

      int user_result {put_entity (
        addr,
        auth_table,
        auth_table_partition,
        userid_0,
        properties
      )};
      cerr << "auth table insertion result " << user_result << endl;
      if (user_result != status_codes::OK) {
        throw std::exception();
      }
    }
    // Create entry 1 authenticating test cases
    {
      vector<pair<string, value>> properties;
      properties.push_back( make_pair(string(auth_pwd_prop), value::string(user_pwd)) );
      properties.push_back( make_pair("DataPartition", value::string(PushFixture::partition)) );
      properties.push_back( make_pair("DataRow", value::string(PushFixture::row_1)) );

      assert(properties.size() == 3);

      int user_result {put_entity (
        addr,
        auth_table,
        auth_table_partition,
        userid_1,
        properties
      )};
      cerr << "auth table insertion result " << user_result << endl;
      if (user_result != status_codes::OK) {
        throw std::exception();
      }
    }
    // Create entry 2 authenticating test cases
    {
      vector<pair<string, value>> properties;
      properties.push_back( make_pair(string(auth_pwd_prop), value::string(user_pwd)) );
      properties.push_back( make_pair("DataPartition", value::string(PushFixture::partition)) );
      properties.push_back( make_pair("DataRow", value::string(PushFixture::row_1)) );

      assert(properties.size() == 3);

      int user_result {put_entity (
        addr,
        auth_table,
        auth_table_partition,
        userid_1,
        properties
      )};
      cerr << "auth table insertion result " << user_result << endl;
      if (user_result != status_codes::OK) {
        throw std::exception();
      }
    }

  }

  ~PushFixture() {

    // Delete entry 0 in DataTable
    {
      int del_ent_result {delete_entity (
        addr,
        table,
        partition,
        row_0
      )};
      cout << "delete datatable result " << del_ent_result << endl;
      if (del_ent_result != status_codes::OK) {
        throw std::exception();
      }
    }
    // Delete entry 1 in DataTable
    {
      int del_ent_result {delete_entity (
        addr,
        table,
        partition,
        row_1
      )};
      cout << "delete datatable result " << del_ent_result << endl;
      if (del_ent_result != status_codes::OK) {
        throw std::exception();
      }
    }
  // Delete entry 2 in DataTable
    {
      int del_ent_result {delete_entity (
        addr,
        table,
        partition,
        row_2
      )};
      cout << "delete datatable result " << del_ent_result << endl;
      if (del_ent_result != status_codes::OK) {
        throw std::exception();
      }
    }

    // Delete entry 0 in AuthTable
    {
      int del_ent_result {delete_entity (
        addr,
        auth_table,
        auth_table_partition,
        userid_0
      )};
      cout << "delete authtable result " << del_ent_result << endl;
      if (del_ent_result != status_codes::OK) {
        throw std::exception();
      }
    }
    // Delete entry 1 in AuthTable
    {
      int del_ent_result {delete_entity (
        addr,
        auth_table,
        auth_table_partition,
        userid_1
      )};
      cout << "delete authtable result " << del_ent_result << endl;
      if (del_ent_result != status_codes::OK) {
        throw std::exception();
      }
    }
    // Delete entry 2 in AuthTable
    {
      int del_ent_result {delete_entity (
        addr,
        auth_table,
        auth_table_partition,
        userid_2
      )};
      cout << "delete authtable result " << del_ent_result << endl;
      if (del_ent_result != status_codes::OK) {
        throw std::exception();
      }
    }

  }
};<commit_msg>fix issue with braces in initializing of fixture<commit_after>/*
  This C++ file contains unit tests for the push server.
 */

#include <algorithm>
#include <exception>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

#include <cpprest/http_client.h>
#include <cpprest/json.h>

#include <pplx/pplxtasks.h>

#include <UnitTest++/UnitTest++.h>
#include <UnitTest++/TestReporterStdout.h>

#include "tester-utils.h"

using std::cout;
using std::cerr;
using std::endl;
using std::make_pair;
using std::pair;
using std::string;
using std::vector;

using web::http::http_headers;
using web::http::http_request;
using web::http::http_response;
using web::http::method;
using web::http::methods;
using web::http::status_code;
using web::http::status_codes;
using web::http::uri_builder;

using web::http::client::http_client;

using web::json::object;
using web::json::value;

using namespace rest_operations;

class PushFixture {
public:

  // User Entity 0
  static constexpr const char* userid_0 {"user_0"};
  static constexpr const char* row_0 {"0,Ben"};

  static constexpr const char* friends_val_0 {"1,Ben|2,Ben"};
  static constexpr const char* status_val_0 {"A status update which is 47 characters long by 0"};
  static constexpr const char* status_update_0 {"A status update which is 52 characters long by 0"};

  // User Entity 1
  static constexpr const char* userid_1 {"user_1"};
  static constexpr const char* row_1 {"1,Ben"};

  static constexpr const char* friends_val_1 {"0,Ben|2,Ben"};
  static constexpr const char* status_val_1 {"A status update which is 47 characters long by 1"};
  static constexpr const char* status_update_1 {"A status update which is 52 characters long by 1"};

  // User Entity 2
  static constexpr const char* userid_2 {"user_2"};
  static constexpr const char* row_2 {"2,Ben"};

  static constexpr const char* friends_val_2 {"0,Ben|1,Ben"};
  static constexpr const char* status_val_2 {"A status update which is 47 characters long by 2"};
  static constexpr const char* status_update_2 {"A status update which is 52 characters long by 2"};

  // Constants for initializing tests
  // Represents a user's credentials
  static constexpr const char* addr {"http://localhost:34568/"};
  static constexpr const char* auth_addr {"http://localhost:34570/"};
  static constexpr const char* user_addr {"http://localhost:34572/"};
  static constexpr const char* user_pwd {"user"};
  static constexpr const char* auth_table {"AuthTable"};
  static constexpr const char* auth_table_partition {"Userid"};
  static constexpr const char* auth_pwd_prop {"Password"};

  // Represents the user's entry including friends and status
  static constexpr const char* table {"DataTable"};
  static constexpr const char* partition {"USA"};
  static constexpr const char* friends {"Friends"};
  static constexpr const char* status {"Status"};
  static constexpr const char* updates {"Updates"};
  static constexpr const char* updates_val {""};

public:
  PushFixture() {

    // Create table DataTable and add a test entry
    {
      int make_result {create_table(addr, table)};
      cerr << "create result " << make_result << endl;
      if (make_result != status_codes::Created && make_result != status_codes::Accepted) {
        throw std::exception();
      }
      //Create entity 0 in DataTable
      int put_result {put_entity (
        addr,
        table,
        partition,
        row_0,
        vector<pair<string,value>>{make_pair(string(friends),value::string(friends_val_0)),
          make_pair(string(status),value::string(status_val_0)),
          make_pair(string(updates),value::string(updates_val))
        }
      )};
      cerr << "data table insertion result " << put_result << endl;
      if (put_result != status_codes::OK) {
        throw std::exception();
      }
      // Create entity 1 in DataTable
      put_result = put_entity (
        addr,
        table,
        partition,
        row_1,
        vector<pair<string,value>>{make_pair(string(friends),value::string(friends_val_1)),
          make_pair(string(status),value::string(status_val_1)),
          make_pair(string(updates),value::string(updates_val))
        }
      );
      cerr << "data table insertion result " << put_result << endl;
      if (put_result != status_codes::OK) {
        throw std::exception();
      }
      // Create entity 2 in DataTable
      put_result = put_entity (
        addr,
        table,
        partition,
        row_2,
        vector<pair<string,value>>{make_pair(string(friends),value::string(friends_val_2)),
          make_pair(string(status),value::string(status_val_2)),
          make_pair(string(updates),value::string(updates_val))
        }
      );
      cerr << "data table insertion result " << put_result << endl;
      if (put_result != status_codes::OK) {
        throw std::exception();
      }
    }

    // Create table AuthTable and add an entry 0 authenticating the test case
    // in DataTable
    {
      int make_result {create_table(addr, auth_table)};
      cerr << "create result " << make_result << endl;
      if (make_result != status_codes::Created && make_result != status_codes::Accepted) {
        throw std::exception();
      }

      vector<pair<string, value>> properties;
      properties.push_back( make_pair(string(auth_pwd_prop), value::string(user_pwd)) );
      properties.push_back( make_pair("DataPartition", value::string(PushFixture::partition)) );
      properties.push_back( make_pair("DataRow", value::string(PushFixture::row_0)) );

      assert(properties.size() == 3);

      int user_result {put_entity (
        addr,
        auth_table,
        auth_table_partition,
        userid_0,
        properties
      )};
      cerr << "auth table insertion result " << user_result << endl;
      if (user_result != status_codes::OK) {
        throw std::exception();
      }
    }
    // Create entry 1 authenticating test cases
    {
      vector<pair<string, value>> properties;
      properties.push_back( make_pair(string(auth_pwd_prop), value::string(user_pwd)) );
      properties.push_back( make_pair("DataPartition", value::string(PushFixture::partition)) );
      properties.push_back( make_pair("DataRow", value::string(PushFixture::row_1)) );

      assert(properties.size() == 3);

      int user_result {put_entity (
        addr,
        auth_table,
        auth_table_partition,
        userid_1,
        properties
      )};
      cerr << "auth table insertion result " << user_result << endl;
      if (user_result != status_codes::OK) {
        throw std::exception();
      }
    }
    // Create entry 2 authenticating test cases
    {
      vector<pair<string, value>> properties;
      properties.push_back( make_pair(string(auth_pwd_prop), value::string(user_pwd)) );
      properties.push_back( make_pair("DataPartition", value::string(PushFixture::partition)) );
      properties.push_back( make_pair("DataRow", value::string(PushFixture::row_1)) );

      assert(properties.size() == 3);

      int user_result {put_entity (
        addr,
        auth_table,
        auth_table_partition,
        userid_1,
        properties
      )};
      cerr << "auth table insertion result " << user_result << endl;
      if (user_result != status_codes::OK) {
        throw std::exception();
      }
    }

  }

  ~PushFixture() {

    // Delete entry 0 in DataTable
    {
      int del_ent_result {delete_entity (
        addr,
        table,
        partition,
        row_0
      )};
      cout << "delete datatable result " << del_ent_result << endl;
      if (del_ent_result != status_codes::OK) {
        throw std::exception();
      }
    }
    // Delete entry 1 in DataTable
    {
      int del_ent_result {delete_entity (
        addr,
        table,
        partition,
        row_1
      )};
      cout << "delete datatable result " << del_ent_result << endl;
      if (del_ent_result != status_codes::OK) {
        throw std::exception();
      }
    }
  // Delete entry 2 in DataTable
    {
      int del_ent_result {delete_entity (
        addr,
        table,
        partition,
        row_2
      )};
      cout << "delete datatable result " << del_ent_result << endl;
      if (del_ent_result != status_codes::OK) {
        throw std::exception();
      }
    }

    // Delete entry 0 in AuthTable
    {
      int del_ent_result {delete_entity (
        addr,
        auth_table,
        auth_table_partition,
        userid_0
      )};
      cout << "delete authtable result " << del_ent_result << endl;
      if (del_ent_result != status_codes::OK) {
        throw std::exception();
      }
    }
    // Delete entry 1 in AuthTable
    {
      int del_ent_result {delete_entity (
        addr,
        auth_table,
        auth_table_partition,
        userid_1
      )};
      cout << "delete authtable result " << del_ent_result << endl;
      if (del_ent_result != status_codes::OK) {
        throw std::exception();
      }
    }
    // Delete entry 2 in AuthTable
    {
      int del_ent_result {delete_entity (
        addr,
        auth_table,
        auth_table_partition,
        userid_2
      )};
      cout << "delete authtable result " << del_ent_result << endl;
      if (del_ent_result != status_codes::OK) {
        throw std::exception();
      }
    }

  }
};<|endoftext|>


<commit_before>/**
 * Copyright 2013 Da Zheng
 *
 * This file is part of SA-GraphLib.
 *
 * SA-GraphLib is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * SA-GraphLib is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with SA-GraphLib.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "common.h"
#include "native_file.h"

#include "vertex_index.h"

vertex_index *vertex_index::load(const std::string &index_file)
{
	native_file local_f(index_file);
	ssize_t size = local_f.get_size();
	assert((unsigned) size >= sizeof(vertex_index));
	char *buf = (char *) malloc(size);
	FILE *fd = fopen(index_file.c_str(), "r");
	size_t ret = fread(buf, size, 1, fd);
	assert(ret == 1);

	vertex_index *idx = (vertex_index *) buf;
	assert((unsigned) size >= sizeof(vertex_index)
			+ idx->get_num_vertices() * sizeof(idx->vertex_offs[0]));
	idx->header.verify();

	return idx;
}

void vertex_index::dump(const std::string &file)
{
	FILE *f = fopen(file.c_str(), "w");
	if (f == NULL) {
		perror("fopen");
		assert(0);
	}

	ssize_t ret = fwrite(this, get_serialize_size(), 1, f);
	assert(ret);

	fclose(f);
}
<commit_msg>[Graph]: fix a bug in load vertex index.<commit_after>/**
 * Copyright 2013 Da Zheng
 *
 * This file is part of SA-GraphLib.
 *
 * SA-GraphLib is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * SA-GraphLib is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with SA-GraphLib.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "common.h"
#include "native_file.h"

#include "vertex_index.h"

vertex_index *vertex_index::load(const std::string &index_file)
{
	native_file local_f(index_file);
	ssize_t size = local_f.get_size();
	assert((unsigned) size >= sizeof(vertex_index));
	char *buf = (char *) malloc(size);
	FILE *fd = fopen(index_file.c_str(), "r");
	size_t ret = fread(buf, size, 1, fd);
	assert(ret == 1);
	fclose(fd);

	vertex_index *idx = (vertex_index *) buf;
	assert((unsigned) size >= sizeof(vertex_index)
			+ idx->get_num_vertices() * sizeof(idx->vertex_offs[0]));
	idx->header.verify();

	return idx;
}

void vertex_index::dump(const std::string &file)
{
	FILE *f = fopen(file.c_str(), "w");
	if (f == NULL) {
		perror("fopen");
		assert(0);
	}

	ssize_t ret = fwrite(this, get_serialize_size(), 1, f);
	assert(ret);

	fclose(f);
}
<|endoftext|>


<commit_before>// we do not test with matlab here
#define USE_MATLAB 0

#include "impl/int_single_nnf.h"
#include "impl/int_nnf_container.h"
#include "voting/weighted_average.h"

#include <cassert>
#include <cmath>
#include <iostream>

using namespace pm;

typedef NearestNeighborField<Patch2ti, float, 1> NNF;
typedef Distance<Patch2ti, float> DistanceFunc;

namespace pm {

    template <int channels = 1>
    struct VoteOperation {

        typedef VoteOperation<channels + 1> Next;

        Image compute() const{
            PixelContainer<channels, Patch2ti, float> data(nnf);
            return weighted_average(data, *filter);
        }

        VoteOperation(const VoteOperation<channels-1> &v) :  nnf(v.nnf), filter(v.filter) {}
        VoteOperation(NNF *n, Filter *f) : nnf(n), filter(f) {}

        NNF *nnf;
        Filter *filter;
    };

}

/**
 * Test the basic integer 1-nnf
 */
int main() {

    Patch2ti::width(7); // set patch size
    assert(Patch2ti::width() == 7 && "Patch width did not update correctly.");
    assert(Patch2tf::width() == 7 && "Patch width isn't spread correctly.");
    seed(timeSeed()); // set rng state

    // create source and target (gradients)
    Image source(100, 100, IM_32FC3);
    for(const auto &i : source){
        auto &v = source.at<Vec3f>(i);
        v[0] = i.x;
        v[1] = i.y;
        v[2] = 0;
    }
    Image target(200, 50, IM_32FC3);
    for(const auto &i : target){
        auto &v = target.at<Vec3f>(i);
        v[0] = i.x;
        v[1] = 0;
        v[2] = i.y;
    }

    // create distance instance
    DistanceFunc d = DistanceFactory<Patch2ti, float>::get(dist::SSD, 3);
    assert(d && "Null distance pointer!");

    // create nnf
    NNF nnf(source, target, d);
    for(const auto &i : nnf){
        nnf.init(i); // random init of patches
    }

    // filter
    Filter filter(7);

    // vote result
    VoteOperation<1> op(&nnf, &filter);
    Image img = vote(op, source.channels());

    // check that pixels are valid (more to be done!)
    for(const Point2i &i : img){
        const Vec3f &v = img->at<Vec3f>(i);
        for(int i = 0; i < 3; ++i){
            assert(v[i] >= 0 && "Negative pixel value!");
        }
    }

    return 0;
}

<commit_msg>Fixed vote test pointer syntax error<commit_after>// we do not test with matlab here
#define USE_MATLAB 0

#include "impl/int_single_nnf.h"
#include "impl/int_nnf_container.h"
#include "math/mat.h"
#include "math/vec.h"
#include "voting/weighted_average.h"

#include <cassert>
#include <cmath>
#include <iostream>

using namespace pm;

typedef NearestNeighborField<Patch2ti, float, 1> NNF;
typedef Distance<Patch2ti, float> DistanceFunc;

namespace pm {

    template <int channels = 1>
    struct VoteOperation {

        typedef VoteOperation<channels + 1> Next;

        Image compute() const{
            PixelContainer<channels, Patch2ti, float> data(nnf);
            return weighted_average(data, *filter);
        }

        VoteOperation(const VoteOperation<channels-1> &v) :  nnf(v.nnf), filter(v.filter) {}
        VoteOperation(NNF *n, Filter *f) : nnf(n), filter(f) {}

        NNF *nnf;
        Filter *filter;
    };

}

/**
 * Test the basic integer 1-nnf
 */
int main() {

    Patch2ti::width(7); // set patch size
    assert(Patch2ti::width() == 7 && "Patch width did not update correctly.");
    assert(Patch2tf::width() == 7 && "Patch width isn't spread correctly.");
    seed(timeSeed()); // set rng state

    // create source and target (gradients)
    Image source(100, 100, IM_32FC3);
    for(const auto &i : source){
        auto &v = source.at<Vec3f>(i);
        v[0] = i.x;
        v[1] = i.y;
        v[2] = 0;
    }
    Image target(200, 50, IM_32FC3);
    for(const auto &i : target){
        auto &v = target.at<Vec3f>(i);
        v[0] = i.x;
        v[1] = 0;
        v[2] = i.y;
    }

    // create distance instance
    DistanceFunc d = DistanceFactory<Patch2ti, float>::get(dist::SSD, 3);
    assert(d && "Null distance pointer!");

    // create nnf
    NNF nnf(source, target, d);
    for(const auto &i : nnf){
        nnf.init(i); // random init of patches
    }

    // filter
    Filter filter(7);

    // vote result
    VoteOperation<1> op(&nnf, &filter);
    Image img = vote(op, source.channels());

    // check that pixels are valid (more to be done!)
    for(const Point2i &i : img){
        const Vec3f &v = img.at<Vec3f>(i);
        for(int i = 0; i < 3; ++i){
            assert(v[i] >= 0 && "Negative pixel value!");
        }
    }

    return 0;
}

<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief Aql, query context
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "Aql/Query.h"
#include "Aql/ExecutionBlock.h"
#include "Aql/ExecutionEngine.h"
#include "Aql/ExecutionPlan.h"
#include "Aql/Parser.h"
#include "Aql/V8Executor.h"
#include "Aql/ExecutionEngine.h"
#include "Basics/JsonHelper.h"
#include "BasicsC/json.h"
#include "BasicsC/tri-strings.h"
#include "Utils/AqlTransaction.h"
#include "Utils/Exception.h"
#include "Utils/V8TransactionContext.h"
#include "VocBase/vocbase.h"

using namespace triagens::aql;

// -----------------------------------------------------------------------------
// --SECTION--                                        constructors / destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief creates a query
////////////////////////////////////////////////////////////////////////////////

Query::Query (TRI_vocbase_t* vocbase,
              char const* queryString,
              size_t queryLength,
              TRI_json_t* bindParameters)
  : _vocbase(vocbase),
    _executor(nullptr),
    _queryString(queryString),
    _queryLength(queryLength),
    _type(AQL_QUERY_READ),
    _bindParameters(bindParameters),
    _collections(vocbase),
    _strings() {

  TRI_ASSERT(_vocbase != nullptr);

  _strings.reserve(32);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a query
////////////////////////////////////////////////////////////////////////////////

Query::~Query () {
  if (_executor != nullptr) {
    delete _executor;
    _executor = nullptr;
  }

  // free strings
  for (auto it = _strings.begin(); it != _strings.end(); ++it) {
    TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, const_cast<char*>(*it));
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief extract a region from the query
////////////////////////////////////////////////////////////////////////////////

std::string Query::extractRegion (int line,
                                  int column) const {
  // note: line numbers reported by bison/flex start at 1, columns start at 0
  int currentLine   = 1;
  int currentColumn = 0;

  char c;
  char const* p = _queryString;

  while ((c = *p)) {
    if (currentLine > line ||
        (currentLine >= line && currentColumn >= column)) {
      break;
    }

    if (c == '\n') {
      ++p;
      ++currentLine;
      currentColumn = 0;
    }
    else if (c == '\r') {
      ++p;
      ++currentLine;
      currentColumn = 0;

      // eat a following newline
      if (*p == '\n') {
        ++p;
      }
    }
    else {
      ++currentColumn;
      ++p;
    }
  }

  // p is pointing at the position in the query the parse error occurred at
  TRI_ASSERT(p >= _queryString);

  size_t offset = static_cast<size_t>(p - _queryString);

  static int const   SNIPPET_LENGTH = 32;
  static char const* SNIPPET_SUFFIX = "...";

  if (_queryLength < offset + SNIPPET_LENGTH) {
    // return a copy of the region
    return std::string(_queryString + offset, _queryLength - offset);
  }

  // copy query part
  std::string result(_queryString + offset, SNIPPET_LENGTH);
  result.append(SNIPPET_SUFFIX);

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief register an error
////////////////////////////////////////////////////////////////////////////////

void Query::registerError (int code,
                           char const* details) {

  TRI_ASSERT(code != TRI_ERROR_NO_ERROR);

  if (details == nullptr) {
    THROW_ARANGO_EXCEPTION(code);
  }
  else {
    THROW_ARANGO_EXCEPTION_PARAMS(code, details);
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief execute an AQL query
////////////////////////////////////////////////////////////////////////////////

QueryResult Query::execute () {
  try {
    Parser parser(this);
    parser.parse();

    // put in bind parameters
    parser.ast()->injectBindParameters(_bindParameters);
    // optimize the ast
    parser.ast()->optimize();
    std::cout << "AST: " << triagens::basics::JsonHelper::toString(parser.ast()->toJson(TRI_UNKNOWN_MEM_ZONE)) << "\n";

    triagens::arango::AqlTransaction<triagens::arango::V8TransactionContext<true>> trx(_vocbase, _collections.collections());

    int res = trx.begin();

    if (res != TRI_ERROR_NO_ERROR) {
      return QueryResult(res, TRI_errno_string(res));
    }

    auto plan = ExecutionPlan::instanciateFromAst(parser.ast());

    triagens::basics::Json json(triagens::basics::Json::List);

    try {
      auto engine = ExecutionEngine::instanciateFromPlan(&trx, plan->root());

      try {
        auto root = engine->root();
        root->execute();

        AqlItemBlock* value;

        while (nullptr != (value = root->getOne())) {
          AqlValue val = value->getValue(0, 0);
          TRI_ASSERT(! val.isEmpty());
          auto doc = value->getDocumentCollection(0);
          json.add(val.toJson(doc));
          delete value;
        }

        delete engine;
      }
      catch (...) {
        delete engine;
        throw;
      }
    }
    catch (...) {
      delete plan;
      throw;
    }

    delete plan;
    trx.commit();

    QueryResult result(TRI_ERROR_NO_ERROR);
    result.json = json;
    return result;
  }
  catch (triagens::arango::Exception const& ex) {
    return QueryResult(ex.code(), ex.message());
  }
  catch (...) {
    return QueryResult(TRI_ERROR_OUT_OF_MEMORY, TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY));
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief parse an AQL query
////////////////////////////////////////////////////////////////////////////////

QueryResult Query::parse () {
  try {
    Parser parser(this);
    return parser.parse();
  }
  catch (triagens::arango::Exception const& ex) {
    return QueryResult(ex.code(), ex.message());
  }
  catch (...) {
    return QueryResult(TRI_ERROR_OUT_OF_MEMORY, TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY));
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief explain an AQL query - TODO: implement and determine return type
////////////////////////////////////////////////////////////////////////////////

void Query::explain () {
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get v8 executor
////////////////////////////////////////////////////////////////////////////////

V8Executor* Query::executor () {
  if (_executor == nullptr) {
    // the executor is a singleton per query
    _executor = new V8Executor;
  }

  TRI_ASSERT(_executor != nullptr);
  return _executor;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief register a string
/// the string is freed when the query is destroyed
////////////////////////////////////////////////////////////////////////////////

char* Query::registerString (char const* p,
                             size_t length,
                             bool mustUnescape) {

  if (p == nullptr) {
    THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
  }

  if (length == 0) {
    static char const* empty = "";
    // optimisation for the empty string
    return const_cast<char*>(empty);
  }

  char* copy = nullptr;
  if (mustUnescape) {
    size_t outLength;
    copy = TRI_UnescapeUtf8StringZ(TRI_UNKNOWN_MEM_ZONE, p, length, &outLength);
  }
  else {
    copy = TRI_DuplicateString2Z(TRI_UNKNOWN_MEM_ZONE, p, length);
  }

  if (copy == nullptr) {
    THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
  }

  try {
    _strings.push_back(copy);
  }
  catch (...) {
    THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
  }

  return copy;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<commit_msg>prevent crashes<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief Aql, query context
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "Aql/Query.h"
#include "Aql/ExecutionBlock.h"
#include "Aql/ExecutionEngine.h"
#include "Aql/ExecutionPlan.h"
#include "Aql/Parser.h"
#include "Aql/V8Executor.h"
#include "Aql/ExecutionEngine.h"
#include "Basics/JsonHelper.h"
#include "BasicsC/json.h"
#include "BasicsC/tri-strings.h"
#include "Utils/AqlTransaction.h"
#include "Utils/Exception.h"
#include "Utils/V8TransactionContext.h"
#include "VocBase/vocbase.h"

using namespace triagens::aql;

// -----------------------------------------------------------------------------
// --SECTION--                                        constructors / destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief creates a query
////////////////////////////////////////////////////////////////////////////////

Query::Query (TRI_vocbase_t* vocbase,
              char const* queryString,
              size_t queryLength,
              TRI_json_t* bindParameters)
  : _vocbase(vocbase),
    _executor(nullptr),
    _queryString(queryString),
    _queryLength(queryLength),
    _type(AQL_QUERY_READ),
    _bindParameters(bindParameters),
    _collections(vocbase),
    _strings() {

  TRI_ASSERT(_vocbase != nullptr);

  _strings.reserve(32);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a query
////////////////////////////////////////////////////////////////////////////////

Query::~Query () {
  if (_executor != nullptr) {
    delete _executor;
    _executor = nullptr;
  }

  // free strings
  for (auto it = _strings.begin(); it != _strings.end(); ++it) {
    TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, const_cast<char*>(*it));
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief extract a region from the query
////////////////////////////////////////////////////////////////////////////////

std::string Query::extractRegion (int line,
                                  int column) const {
  // note: line numbers reported by bison/flex start at 1, columns start at 0
  int currentLine   = 1;
  int currentColumn = 0;

  char c;
  char const* p = _queryString;

  while ((c = *p)) {
    if (currentLine > line ||
        (currentLine >= line && currentColumn >= column)) {
      break;
    }

    if (c == '\n') {
      ++p;
      ++currentLine;
      currentColumn = 0;
    }
    else if (c == '\r') {
      ++p;
      ++currentLine;
      currentColumn = 0;

      // eat a following newline
      if (*p == '\n') {
        ++p;
      }
    }
    else {
      ++currentColumn;
      ++p;
    }
  }

  // p is pointing at the position in the query the parse error occurred at
  TRI_ASSERT(p >= _queryString);

  size_t offset = static_cast<size_t>(p - _queryString);

  static int const   SNIPPET_LENGTH = 32;
  static char const* SNIPPET_SUFFIX = "...";

  if (_queryLength < offset + SNIPPET_LENGTH) {
    // return a copy of the region
    return std::string(_queryString + offset, _queryLength - offset);
  }

  // copy query part
  std::string result(_queryString + offset, SNIPPET_LENGTH);
  result.append(SNIPPET_SUFFIX);

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief register an error
////////////////////////////////////////////////////////////////////////////////

void Query::registerError (int code,
                           char const* details) {

  TRI_ASSERT(code != TRI_ERROR_NO_ERROR);

  if (details == nullptr) {
    THROW_ARANGO_EXCEPTION(code);
  }
  else {
    THROW_ARANGO_EXCEPTION_PARAMS(code, details);
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief execute an AQL query
////////////////////////////////////////////////////////////////////////////////

QueryResult Query::execute () {
  try {
    Parser parser(this);
    parser.parse();

    // put in bind parameters
    parser.ast()->injectBindParameters(_bindParameters);
    // optimize the ast
    parser.ast()->optimize();
    std::cout << "AST: " << triagens::basics::JsonHelper::toString(parser.ast()->toJson(TRI_UNKNOWN_MEM_ZONE)) << "\n";

    triagens::arango::AqlTransaction<triagens::arango::V8TransactionContext<true>> trx(_vocbase, _collections.collections());

    int res = trx.begin();

    if (res != TRI_ERROR_NO_ERROR) {
      return QueryResult(res, TRI_errno_string(res));
    }

    auto plan = ExecutionPlan::instanciateFromAst(parser.ast());

    triagens::basics::Json json(triagens::basics::Json::List);

    try {
      auto engine = ExecutionEngine::instanciateFromPlan(&trx, plan->root());

      try {
        auto root = engine->root();
        root->execute();

        AqlItemBlock* value;

        while (nullptr != (value = root->getOne())) {
          AqlValue val = value->getValue(0, 0);

          if (! val.isEmpty()) {
            auto doc = value->getDocumentCollection(0);
            json.add(val.toJson(doc));
          }
          delete value;
        }

        delete engine;
      }
      catch (...) {
        delete engine;
        throw;
      }
    }
    catch (...) {
      delete plan;
      throw;
    }

    delete plan;
    trx.commit();

    QueryResult result(TRI_ERROR_NO_ERROR);
    result.json = json;
    return result;
  }
  catch (triagens::arango::Exception const& ex) {
    return QueryResult(ex.code(), ex.message());
  }
  catch (...) {
    return QueryResult(TRI_ERROR_OUT_OF_MEMORY, TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY));
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief parse an AQL query
////////////////////////////////////////////////////////////////////////////////

QueryResult Query::parse () {
  try {
    Parser parser(this);
    return parser.parse();
  }
  catch (triagens::arango::Exception const& ex) {
    return QueryResult(ex.code(), ex.message());
  }
  catch (...) {
    return QueryResult(TRI_ERROR_OUT_OF_MEMORY, TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY));
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief explain an AQL query - TODO: implement and determine return type
////////////////////////////////////////////////////////////////////////////////

void Query::explain () {
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get v8 executor
////////////////////////////////////////////////////////////////////////////////

V8Executor* Query::executor () {
  if (_executor == nullptr) {
    // the executor is a singleton per query
    _executor = new V8Executor;
  }

  TRI_ASSERT(_executor != nullptr);
  return _executor;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief register a string
/// the string is freed when the query is destroyed
////////////////////////////////////////////////////////////////////////////////

char* Query::registerString (char const* p,
                             size_t length,
                             bool mustUnescape) {

  if (p == nullptr) {
    THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
  }

  if (length == 0) {
    static char const* empty = "";
    // optimisation for the empty string
    return const_cast<char*>(empty);
  }

  char* copy = nullptr;
  if (mustUnescape) {
    size_t outLength;
    copy = TRI_UnescapeUtf8StringZ(TRI_UNKNOWN_MEM_ZONE, p, length, &outLength);
  }
  else {
    copy = TRI_DuplicateString2Z(TRI_UNKNOWN_MEM_ZONE, p, length);
  }

  if (copy == nullptr) {
    THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
  }

  try {
    _strings.push_back(copy);
  }
  catch (...) {
    THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
  }

  return copy;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<|endoftext|>


<commit_before>/*
    identitystatuswidget.cpp  -  Kopete identity status configuration widget

    Copyright (c) 2007      by Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>

    Kopete    (c) 2003-2007 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "identitystatuswidget.h"
#include "ui_identitystatusbase.h"

#include <KIcon>
#include <KMenu>
#include <QTimeLine>
#include <QCursor>
#include <QUrl>
#include <QPalette>
#include <kopeteidentity.h>
#include <kopeteaccount.h>
#include <kopeteaccountmanager.h>
#include <kopetecontact.h>
#include <kopeteprotocol.h>
#include <avatardialog.h>
#include <KDebug>

class IdentityStatusWidget::Private
{
public:
	Kopete::Identity *identity;
	Ui::IdentityStatusBase ui;
	QTimeLine *timeline;
	QString photoPath;
	// Used to display changing nickname in red
	QString lastNickName;
};

IdentityStatusWidget::IdentityStatusWidget(Kopete::Identity *identity, QWidget *parent)
: QWidget(parent)
{
	d = new Private();
	d->identity = identity;

	// animation for showing/hiding
	d->timeline = new QTimeLine( 150, this );
	d->timeline->setCurveShape( QTimeLine::EaseInOutCurve );
	connect( d->timeline, SIGNAL(valueChanged(qreal)),
			 this, SLOT(slotAnimate(qreal)) );

	d->ui.setupUi(this);
	QWidget::setVisible( false );

	slotLoad();

	// user input signals
	connect( d->ui.nickName, SIGNAL(editingFinished()), this, SLOT(slotSave()) );
	connect( d->ui.nickName, SIGNAL(textChanged(QString)), this, SLOT(slotNickNameTextChanged(QString)) );
	connect( d->ui.photo, SIGNAL(linkActivated(const QString&)),
			 this, SLOT(slotPhotoLinkActivated(const QString &)));
	connect( d->ui.accounts, SIGNAL(linkActivated(const QString&)),
			 this, SLOT(slotAccountLinkActivated(const QString &)));
	connect( Kopete::AccountManager::self(),
			SIGNAL(accountOnlineStatusChanged(Kopete::Account*, const Kopete::OnlineStatus&, const Kopete::OnlineStatus&)),
			this, SLOT(slotUpdateAccountStatus()));
}

IdentityStatusWidget::~IdentityStatusWidget()
{
	delete d->timeline;
	delete d;
}

void IdentityStatusWidget::setIdentity(Kopete::Identity *identity)
{
	if (d->identity)
		slotSave();

	d->identity = identity;
	slotLoad();
}

Kopete::Identity *IdentityStatusWidget::identity() const
{
	return d->identity;
}

void IdentityStatusWidget::setVisible( bool visible )
{
	// animate the widget disappearing
	d->timeline->setDirection( visible ?  QTimeLine::Forward
										: QTimeLine::Backward );
	d->timeline->start();
}

void IdentityStatusWidget::slotAnimate(qreal amount)
{
	if (amount == 0)
	{
		QWidget::setVisible( false );
		return;
	}

	if (amount == 1)
	{
		setFixedHeight( sizeHint().height() );
		d->ui.nickName->setFocus();
		return;
	}

	if (!isVisible())
		QWidget::setVisible( true );

	setFixedHeight( sizeHint().height() * amount );
}

void IdentityStatusWidget::slotLoad()
{
	// clear
	d->ui.photo->setText(QString("%1").arg(i18n("No Photo")));
	d->ui.nickName->clear();
	d->ui.identityStatus->clear();
	d->ui.identityName->clear();
	d->ui.accounts->clear();

	if (!d->identity)
		return;

	Kopete::Global::Properties *props = Kopete::Global::Properties::self();

	// photo
	if (d->identity->hasProperty(props->photo().key()))
	{
		d->photoPath = d->identity->property(props->photo()).value().toString();
		d->ui.photo->setText(QString("")
								.arg(d->photoPath));
	}

	// nickname
	if (d->identity->hasProperty(props->nickName().key()))
	{
		// Set lastNickName to make red highlighting works when editing the identity nickname
		d->lastNickName = d->identity->property(props->nickName()).value().toString();

		d->ui.nickName->setText( d->lastNickName );
	}

	d->ui.identityName->setText(d->identity->identityId());

	//acounts
	slotUpdateAccountStatus();
	//TODO: online status

}

void IdentityStatusWidget::slotNickNameTextChanged(const QString &text)
{
	if ( d->lastNickName != text )
	{
		QPalette palette;
		palette.setColor(d->ui.nickName->foregroundRole(), Qt::red);
		d->ui.nickName->setPalette(palette);
	}
	else
	{
		// If the nickname is the same, reset the palette
		d->ui.nickName->setPalette(QPalette());
	}

}

void IdentityStatusWidget::slotSave()
{
	if (!d->identity)
		return;

	Kopete::Global::Properties *props = Kopete::Global::Properties::self();

	// photo
	if (!d->identity->hasProperty(props->photo().key()) ||
		d->identity->property(props->photo()).value().toString() != d->photoPath)
	{
		d->identity->setProperty(props->photo(), d->photoPath);
	}

	// nickname
	if (!d->identity->hasProperty(props->nickName().key()) ||
		d->identity->property(props->photo()).value().toString() != d->ui.nickName->text())
	{
		d->identity->setProperty(props->nickName(), d->ui.nickName->text());

		// Set last nickname to the new identity nickname
		// and reset the palette
		d->lastNickName = d->ui.nickName->text();
		d->ui.nickName->setPalette(QPalette());
	}

	//TODO check what more to do

}

void IdentityStatusWidget::slotAccountLinkActivated(const QString &link)
{
	// Account links are in the form:
	// accountmenu:protocolId:accountId
	QStringList args = link.split(":");
	if (args[0] != "accountmenu")
		return;

	Kopete::Account *a = Kopete::AccountManager::self()->findAccount(QUrl::fromPercentEncoding(args[1].toAscii()),
																	 QUrl::fromPercentEncoding(args[2].toAscii()));
	if (!a)
		return;

	a->actionMenu()->menu()->exec(QCursor::pos());
}

void IdentityStatusWidget::slotPhotoLinkActivated(const QString &link)
{
	if (link == "identity::getavatar")
	{
		d->photoPath = Kopete::UI::AvatarDialog::getAvatar(this, d->photoPath);
		slotSave();
		slotLoad();
	}
}

void IdentityStatusWidget::slotUpdateAccountStatus()
{
  if (!d->identity)
  {
    // no identity or already destroyed, ignore
    return;
  }

  // Always clear text before changing it: otherwise icon changes are not reflected
  d->ui.accounts->clear();

  QString text("<qt>");
  foreach(Kopete::Account *a, d->identity->accounts())
  {
	  Kopete::Contact *self = a->myself();
	  QString onlineStatus = self ? self->onlineStatus().description() : i18n("Offline");
	  text += i18nc( "Account tooltip information: <nobr>ICON PROTOCOL: NAME (STATUS)
",
				    "<nobr> %1 (%4)
",
		a->accountLabel(), QString(QUrl::toPercentEncoding( a->protocol()->pluginId() )),
		QString(QUrl::toPercentEncoding( a->accountId() )), onlineStatus );
  }

  text += QLatin1String("</qt>");
  d->ui.accounts->setText( text );
}

#include "identitystatuswidget.moc"
// vim: set noet ts=4 sts=4 sw=4:

<commit_msg>Update identity widget if accounts are added or removed, and make sure widget height is set properly BUG: 150371<commit_after>/*
    identitystatuswidget.cpp  -  Kopete identity status configuration widget

    Copyright (c) 2007      by Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>

    Kopete    (c) 2003-2007 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "identitystatuswidget.h"
#include "ui_identitystatusbase.h"

#include <KIcon>
#include <KMenu>
#include <QTimeLine>
#include <QCursor>
#include <QUrl>
#include <QPalette>
#include <kopeteidentity.h>
#include <kopeteaccount.h>
#include <kopeteaccountmanager.h>
#include <kopetecontact.h>
#include <kopeteprotocol.h>
#include <avatardialog.h>
#include <KDebug>

class IdentityStatusWidget::Private
{
public:
	Kopete::Identity *identity;
	Ui::IdentityStatusBase ui;
	QTimeLine *timeline;
	QString photoPath;
	// Used to display changing nickname in red
	QString lastNickName;
};

IdentityStatusWidget::IdentityStatusWidget(Kopete::Identity *identity, QWidget *parent)
: QWidget(parent)
{
	d = new Private();
	d->identity = 0;

	// animation for showing/hiding
	d->timeline = new QTimeLine( 150, this );
	d->timeline->setCurveShape( QTimeLine::EaseInOutCurve );
	connect( d->timeline, SIGNAL(valueChanged(qreal)),
			 this, SLOT(slotAnimate(qreal)) );

	d->ui.setupUi(this);
	QWidget::setVisible( false );

	setIdentity(identity);
	slotLoad();

	// user input signals
	connect( d->ui.nickName, SIGNAL(editingFinished()), this, SLOT(slotSave()) );
	connect( d->ui.nickName, SIGNAL(textChanged(QString)), this, SLOT(slotNickNameTextChanged(QString)) );
	connect( d->ui.photo, SIGNAL(linkActivated(const QString&)),
			 this, SLOT(slotPhotoLinkActivated(const QString &)));
	connect( d->ui.accounts, SIGNAL(linkActivated(const QString&)),
			 this, SLOT(slotAccountLinkActivated(const QString &)));
	connect( Kopete::AccountManager::self(),
			SIGNAL(accountOnlineStatusChanged(Kopete::Account*, const Kopete::OnlineStatus&, const Kopete::OnlineStatus&)),
			this, SLOT(slotUpdateAccountStatus()));
}

IdentityStatusWidget::~IdentityStatusWidget()
{
	delete d->timeline;
	delete d;
}

void IdentityStatusWidget::setIdentity(Kopete::Identity *identity)
{
	if (d->identity)
	{
		disconnect( d->identity, SIGNAL(identityChanged(Kopete::Identity*)), this, SLOT(slotUpdateAccountStatus()));
		slotSave();
	}

	d->identity = identity;
	slotLoad();

	if (d->identity)
	{
		connect( d->identity, SIGNAL(identityChanged(Kopete::Identity*)), this, SLOT(slotUpdateAccountStatus()));
	}
}

Kopete::Identity *IdentityStatusWidget::identity() const
{
	return d->identity;
}

void IdentityStatusWidget::setVisible( bool visible )
{
	// animate the widget disappearing
	d->timeline->setDirection( visible ?  QTimeLine::Forward
										: QTimeLine::Backward );
	d->timeline->start();
}

void IdentityStatusWidget::slotAnimate(qreal amount)
{
	if (amount == 0)
	{
		QWidget::setVisible( false );
		return;
	}

	if (amount == 1)
	{
		setFixedHeight( sizeHint().height() );
		d->ui.nickName->setFocus();
		return;
	}

	if (!isVisible())
		QWidget::setVisible( true );

	setFixedHeight( sizeHint().height() * amount );
}

void IdentityStatusWidget::slotLoad()
{
	// clear
	d->ui.photo->setText(QString("%1").arg(i18n("No Photo")));
	d->ui.nickName->clear();
	d->ui.identityStatus->clear();
	d->ui.identityName->clear();
	d->ui.accounts->clear();

	if (!d->identity)
		return;

	Kopete::Global::Properties *props = Kopete::Global::Properties::self();

	// photo
	if (d->identity->hasProperty(props->photo().key()))
	{
		d->photoPath = d->identity->property(props->photo()).value().toString();
		d->ui.photo->setText(QString("")
								.arg(d->photoPath));
	}

	// nickname
	if (d->identity->hasProperty(props->nickName().key()))
	{
		// Set lastNickName to make red highlighting works when editing the identity nickname
		d->lastNickName = d->identity->property(props->nickName()).value().toString();

		d->ui.nickName->setText( d->lastNickName );
	}

	d->ui.identityName->setText(d->identity->identityId());

	//acounts
	slotUpdateAccountStatus();
	//TODO: online status

}

void IdentityStatusWidget::slotNickNameTextChanged(const QString &text)
{
	if ( d->lastNickName != text )
	{
		QPalette palette;
		palette.setColor(d->ui.nickName->foregroundRole(), Qt::red);
		d->ui.nickName->setPalette(palette);
	}
	else
	{
		// If the nickname is the same, reset the palette
		d->ui.nickName->setPalette(QPalette());
	}

}

void IdentityStatusWidget::slotSave()
{
	if (!d->identity)
		return;

	Kopete::Global::Properties *props = Kopete::Global::Properties::self();

	// photo
	if (!d->identity->hasProperty(props->photo().key()) ||
		d->identity->property(props->photo()).value().toString() != d->photoPath)
	{
		d->identity->setProperty(props->photo(), d->photoPath);
	}

	// nickname
	if (!d->identity->hasProperty(props->nickName().key()) ||
		d->identity->property(props->photo()).value().toString() != d->ui.nickName->text())
	{
		d->identity->setProperty(props->nickName(), d->ui.nickName->text());

		// Set last nickname to the new identity nickname
		// and reset the palette
		d->lastNickName = d->ui.nickName->text();
		d->ui.nickName->setPalette(QPalette());
	}

	//TODO check what more to do

}

void IdentityStatusWidget::slotAccountLinkActivated(const QString &link)
{
	// Account links are in the form:
	// accountmenu:protocolId:accountId
	QStringList args = link.split(":");
	if (args[0] != "accountmenu")
		return;

	Kopete::Account *a = Kopete::AccountManager::self()->findAccount(QUrl::fromPercentEncoding(args[1].toAscii()),
																	 QUrl::fromPercentEncoding(args[2].toAscii()));
	if (!a)
		return;

	a->actionMenu()->menu()->exec(QCursor::pos());
}

void IdentityStatusWidget::slotPhotoLinkActivated(const QString &link)
{
	if (link == "identity::getavatar")
	{
		d->photoPath = Kopete::UI::AvatarDialog::getAvatar(this, d->photoPath);
		slotSave();
		slotLoad();
	}
}

void IdentityStatusWidget::slotUpdateAccountStatus()
{
  if (!d->identity)
  {
    // no identity or already destroyed, ignore
    return;
  }

  // Always clear text before changing it: otherwise icon changes are not reflected
  d->ui.accounts->clear();

  QString text("<qt>");
  foreach(Kopete::Account *a, d->identity->accounts())
  {
	  Kopete::Contact *self = a->myself();
	  QString onlineStatus = self ? self->onlineStatus().description() : i18n("Offline");
	  text += i18nc( "Account tooltip information: <nobr>ICON PROTOCOL: NAME (STATUS)
",
				    "<nobr> %1 (%4)
",
		a->accountLabel(), QString(QUrl::toPercentEncoding( a->protocol()->pluginId() )),
		QString(QUrl::toPercentEncoding( a->accountId() )), onlineStatus );
  }

  text += QLatin1String("</qt>");
  d->ui.accounts->setText( text );

  // Adding/removing accounts changes needed size
  setFixedHeight( sizeHint().height() );
}

#include "identitystatuswidget.moc"
// vim: set noet ts=4 sts=4 sw=4:

<|endoftext|>


<commit_before>#include "searchengine.h"

#include "utilities/predictioncollection.h"

#include <QPair>
#include <QVector>
#include <QtAlgorithms>

namespace sp = Spotinetta;

namespace Sonetta {

SearchEngine::SearchEngine(const Spotinetta::Session *session, QObject *parent)
    : QObject(parent), m_session(session)
{
    m_watcher = new sp::SearchWatcher(session, this);
    m_predictionWatcher = new sp::SearchWatcher(session, this);
    m_trackModel = new TrackListModel(this);
    m_albumModel = new AlbumListModel(this);
    m_artistModel = new ArtistListModel(this);

    // Initialize offsets and deltas to reasonable values
    m_albumOffset
            = m_trackOffset
            = m_artistOffset
            = m_playlistOffset
            = 0;

    m_albumDelta = 10;
    m_trackDelta = 30;
    m_artistDelta = 10;
    m_playlistDelta = 10;

    // Set up connections
    connect(m_watcher, &sp::SearchWatcher::loaded,
            this, &SearchEngine::onSearchLoaded);
    connect(m_predictionWatcher, &sp::SearchWatcher::loaded,
            this, &SearchEngine::onPredictionsLoaded);
}

QString SearchEngine::query() const
{
    return m_query;
}

QStringList SearchEngine::predictions() const
{
    return m_predictions;
}

void SearchEngine::go(const QString &query)
{
    if (m_watcher->watched().query() != query && !m_session.isNull())
    {
        m_query = query;

        // Clean new query, reset offsets
        m_albumOffset = 0;
        m_trackOffset = 0;
        m_artistOffset = 0;
        m_playlistOffset = 0;

        m_trackModel->clear();
        m_albumModel->clear();
        m_artistModel->clear();

        // Reconnect fetchMore if connections are broken (note UniqueConnection)
        connect(m_trackModel, &TrackListModel::needMore,
                this, &SearchEngine::fetchMoreTracks, Qt::UniqueConnection);
        connect(m_artistModel, &ArtistListModel::needMore,
                this, &SearchEngine::fetchMoreArtists, Qt::UniqueConnection);
        connect(m_albumModel, &AlbumListModel::needMore,
                this, &SearchEngine::fetchMoreAlbums, Qt::UniqueConnection);

        performQuery(m_trackDelta, m_albumDelta, m_artistDelta, m_playlistDelta);

        emit queryChanged();
    }
}

void SearchEngine::performQuery(int trackDelta, int albumDelta,
                                int artistDelta, int playlistDelta)
{
    m_lastTrackDelta = trackDelta;
    m_lastPlaylistDelta = playlistDelta;
    m_lastAlbumDelta = albumDelta;
    m_lastArtistDelta = artistDelta;

    sp::Search search = m_session->createSearch(m_query, m_trackOffset, trackDelta,
                                                m_albumOffset, albumDelta,
                                                m_artistOffset, artistDelta,
                                                m_playlistOffset, playlistDelta, sp::Search::Type::Standard);

    m_watcher->watch(search);

    // Search may be cached, in that case we need to check
    // if it was loaded instantaneously (I think?)
    if (search.isLoaded())
    {
        onSearchLoaded();
    }
}

void SearchEngine::onSearchLoaded()
{
    sp::Search search = m_watcher->watched();

    // Disconnect fetch if unable to acquire more results (tracks/albums/artists/playlists)
    if (m_lastTrackDelta > 0 && search.trackCount() < m_lastTrackDelta)
        disconnect(m_trackModel, &TrackListModel::needMore,
                   this, &SearchEngine::fetchMoreTracks);

    if (m_lastAlbumDelta > 0 && search.albumCount() < m_lastAlbumDelta)
        disconnect(m_albumModel, &AlbumListModel::needMore,
                   this, &SearchEngine::fetchMoreAlbums);

    if (m_lastArtistDelta > 0 && search.artistCount() < m_lastArtistDelta)
        disconnect(m_artistModel, &ArtistListModel::needMore,
                   this, &SearchEngine::fetchMoreArtists);

    // Update offsets
    m_albumOffset += search.albumCount();
    m_artistOffset += search.artistCount();
    m_trackOffset += search.trackCount();
    m_playlistOffset += search.playlistCount();

    // Update models
    m_trackModel->append(search.tracks());
    m_albumModel->append(search.albums());
    m_artistModel->append(search.artists());
}

void SearchEngine::fetchMoreTracks()
{
    if (!m_session.isNull())
        performQuery(m_trackDelta, 0, 0, 0);
}

void SearchEngine::fetchMoreArtists()
{
    if (!m_session.isNull())
        performQuery(0, 0, m_artistDelta, 0);
}

void SearchEngine::fetchMorePlaylists()
{
    if (!m_session.isNull())
        performQuery(0, 0, 0, m_lastPlaylistDelta);
}

void SearchEngine::fetchMoreAlbums()
{
    if (!m_session.isNull())
        performQuery(0, m_albumDelta, 0, 0);
}

void SearchEngine::predict(const QString &partial)
{
    if (partial.isEmpty())
    {
        m_predictions.clear();
        emit predictionsChanged();
        return;
    }
    if (!m_session.isNull())
    {
        sp::Search search = m_session->createSearch(partial, 0, 6, 0, 3, 0, 3, 0, 0, sp::Search::Type::Suggest);
        m_predictionWatcher->watch(search);

        if (search.isLoaded())
        {
            onPredictionsLoaded();
        }
    }
}

void SearchEngine::onPredictionsLoaded()
{
    sp::Search search = m_predictionWatcher->watched();

    // Mix track, artist and album predictions.
    sp::TrackList tracks = search.tracks();
    sp::ArtistList artists = search.artists();
    sp::AlbumList albums = search.albums();
    sp::PlaylistList playlists = search.playlists();

    PredictionCollection pred(search.query());

    for (const sp::Track & track : tracks)
    {
        pred.insert(track);
    }

    for (const sp::Artist & artist : artists)
    {
        pred.insert(artist);
    }

    for (const sp::Album & album : albums)
    {
        pred.insert(album);
    }

    for (const sp::Playlist & playlist : playlists)
    {
        pred.insert(playlist);
    }

    QStringList predictions = pred.predictions();
    // Limit to 8 predictions (the 8 best)
    if (predictions.size() > 8)
    {
        predictions.erase(predictions.begin() + 8, predictions.end());
    }

    m_predictions.swap(predictions);
    emit predictionsChanged();
}

}
<commit_msg>Limited predictions 6 suggestions<commit_after>#include "searchengine.h"

#include "utilities/predictioncollection.h"

#include <QPair>
#include <QVector>
#include <QtAlgorithms>

namespace sp = Spotinetta;

namespace Sonetta {

SearchEngine::SearchEngine(const Spotinetta::Session *session, QObject *parent)
    : QObject(parent), m_session(session)
{
    m_watcher = new sp::SearchWatcher(session, this);
    m_predictionWatcher = new sp::SearchWatcher(session, this);
    m_trackModel = new TrackListModel(this);
    m_albumModel = new AlbumListModel(this);
    m_artistModel = new ArtistListModel(this);

    // Initialize offsets and deltas to reasonable values
    m_albumOffset
            = m_trackOffset
            = m_artistOffset
            = m_playlistOffset
            = 0;

    m_albumDelta = 10;
    m_trackDelta = 30;
    m_artistDelta = 10;
    m_playlistDelta = 10;

    // Set up connections
    connect(m_watcher, &sp::SearchWatcher::loaded,
            this, &SearchEngine::onSearchLoaded);
    connect(m_predictionWatcher, &sp::SearchWatcher::loaded,
            this, &SearchEngine::onPredictionsLoaded);
}

QString SearchEngine::query() const
{
    return m_query;
}

QStringList SearchEngine::predictions() const
{
    return m_predictions;
}

void SearchEngine::go(const QString &query)
{
    if (m_watcher->watched().query() != query && !m_session.isNull())
    {
        m_query = query;

        // Clean new query, reset offsets
        m_albumOffset = 0;
        m_trackOffset = 0;
        m_artistOffset = 0;
        m_playlistOffset = 0;

        m_trackModel->clear();
        m_albumModel->clear();
        m_artistModel->clear();

        // Reconnect fetchMore if connections are broken (note UniqueConnection)
        connect(m_trackModel, &TrackListModel::needMore,
                this, &SearchEngine::fetchMoreTracks, Qt::UniqueConnection);
        connect(m_artistModel, &ArtistListModel::needMore,
                this, &SearchEngine::fetchMoreArtists, Qt::UniqueConnection);
        connect(m_albumModel, &AlbumListModel::needMore,
                this, &SearchEngine::fetchMoreAlbums, Qt::UniqueConnection);

        performQuery(m_trackDelta, m_albumDelta, m_artistDelta, m_playlistDelta);

        emit queryChanged();
    }
}

void SearchEngine::performQuery(int trackDelta, int albumDelta,
                                int artistDelta, int playlistDelta)
{
    m_lastTrackDelta = trackDelta;
    m_lastPlaylistDelta = playlistDelta;
    m_lastAlbumDelta = albumDelta;
    m_lastArtistDelta = artistDelta;

    sp::Search search = m_session->createSearch(m_query, m_trackOffset, trackDelta,
                                                m_albumOffset, albumDelta,
                                                m_artistOffset, artistDelta,
                                                m_playlistOffset, playlistDelta, sp::Search::Type::Standard);

    m_watcher->watch(search);

    // Search may be cached, in that case we need to check
    // if it was loaded instantaneously (I think?)
    if (search.isLoaded())
    {
        onSearchLoaded();
    }
}

void SearchEngine::onSearchLoaded()
{
    sp::Search search = m_watcher->watched();

    // Disconnect fetch if unable to acquire more results (tracks/albums/artists/playlists)
    if (m_lastTrackDelta > 0 && search.trackCount() < m_lastTrackDelta)
        disconnect(m_trackModel, &TrackListModel::needMore,
                   this, &SearchEngine::fetchMoreTracks);

    if (m_lastAlbumDelta > 0 && search.albumCount() < m_lastAlbumDelta)
        disconnect(m_albumModel, &AlbumListModel::needMore,
                   this, &SearchEngine::fetchMoreAlbums);

    if (m_lastArtistDelta > 0 && search.artistCount() < m_lastArtistDelta)
        disconnect(m_artistModel, &ArtistListModel::needMore,
                   this, &SearchEngine::fetchMoreArtists);

    // Update offsets
    m_albumOffset += search.albumCount();
    m_artistOffset += search.artistCount();
    m_trackOffset += search.trackCount();
    m_playlistOffset += search.playlistCount();

    // Update models
    m_trackModel->append(search.tracks());
    m_albumModel->append(search.albums());
    m_artistModel->append(search.artists());
}

void SearchEngine::fetchMoreTracks()
{
    if (!m_session.isNull())
        performQuery(m_trackDelta, 0, 0, 0);
}

void SearchEngine::fetchMoreArtists()
{
    if (!m_session.isNull())
        performQuery(0, 0, m_artistDelta, 0);
}

void SearchEngine::fetchMorePlaylists()
{
    if (!m_session.isNull())
        performQuery(0, 0, 0, m_lastPlaylistDelta);
}

void SearchEngine::fetchMoreAlbums()
{
    if (!m_session.isNull())
        performQuery(0, m_albumDelta, 0, 0);
}

void SearchEngine::predict(const QString &partial)
{
    if (partial.isEmpty())
    {
        m_predictions.clear();
        emit predictionsChanged();
        return;
    }
    if (!m_session.isNull())
    {
        sp::Search search = m_session->createSearch(partial, 0, 6, 0, 3, 0, 3, 0, 0, sp::Search::Type::Suggest);
        m_predictionWatcher->watch(search);

        if (search.isLoaded())
        {
            onPredictionsLoaded();
        }
    }
}

void SearchEngine::onPredictionsLoaded()
{
    sp::Search search = m_predictionWatcher->watched();

    // Mix track, artist and album predictions.
    sp::TrackList tracks = search.tracks();
    sp::ArtistList artists = search.artists();
    sp::AlbumList albums = search.albums();
    sp::PlaylistList playlists = search.playlists();

    PredictionCollection pred(search.query());

    for (const sp::Track & track : tracks)
    {
        pred.insert(track);
    }

    for (const sp::Artist & artist : artists)
    {
        pred.insert(artist);
    }

    for (const sp::Album & album : albums)
    {
        pred.insert(album);
    }

    for (const sp::Playlist & playlist : playlists)
    {
        pred.insert(playlist);
    }

    QStringList predictions = pred.predictions();
    // Limit to 6 predictions (the 6 best)
    if (predictions.size() > 6)
    {
        predictions.erase(predictions.begin() + 6, predictions.end());
    }

    m_predictions.swap(predictions);
    emit predictionsChanged();
}

}
<|endoftext|>