void t_py_generator::generate_service_remote()

in compiler/cpp/src/thrift/generate/t_py_generator.cc [1724:1921]


void t_py_generator::generate_service_remote(t_service* tservice) {
  vector<t_function*> functions = tservice->get_functions();
  // Get all function from parents
  t_service* parent = tservice->get_extends();
  while (parent != nullptr) {
    vector<t_function*> p_functions = parent->get_functions();
    functions.insert(functions.end(), p_functions.begin(), p_functions.end());
    parent = parent->get_extends();
  }
  vector<t_function*>::iterator f_iter;

  string f_remote_name = package_dir_ + "/" + service_name_ + "-remote";
  ofstream_with_content_based_conditional_update f_remote;
  f_remote.open(f_remote_name.c_str());

  f_remote <<
    "#!/usr/bin/env python" << '\n' <<
    py_autogen_comment() << '\n' <<
    "import sys" << '\n' <<
    "import pprint" << '\n' <<
    "if sys.version_info[0] > 2:" << '\n' <<
    indent_str() << "from urllib.parse import urlparse" << '\n' <<
    "else:" << '\n' <<
    indent_str() << "from urlparse import urlparse" << '\n' <<
    "from thrift.transport import TTransport, TSocket, TSSLSocket, THttpClient" << '\n' <<
    "from thrift.protocol.TBinaryProtocol import TBinaryProtocol" << '\n' << '\n';

  f_remote <<
    "from " << module_ << " import " << service_name_ << '\n' <<
    "from " << module_ << ".ttypes import *" << '\n' << '\n';

  f_remote <<
    "if len(sys.argv) <= 1 or sys.argv[1] == '--help':" << '\n' <<
    indent_str() << "print('')" << '\n' <<
    indent_str() << "print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] [-novalidate] [-ca_certs certs] [-keyfile keyfile] [-certfile certfile] function [arg1 [arg2...]]')" << '\n' <<
    indent_str() << "print('')" << '\n' <<
    indent_str() << "print('Functions:')" << '\n';
  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
    f_remote << indent_str() << "print('  " << (*f_iter)->get_returntype()->get_name() << " "
             << (*f_iter)->get_name() << "(";
    t_struct* arg_struct = (*f_iter)->get_arglist();
    const std::vector<t_field*>& args = arg_struct->get_members();
    std::vector<t_field*>::size_type num_args = args.size();
    bool first = true;
    for (std::vector<t_field*>::size_type i = 0; i < num_args; ++i) {
      if (first) {
        first = false;
      } else {
        f_remote << ", ";
      }
      f_remote << args[i]->get_type()->get_name() << " " << args[i]->get_name();
    }
    f_remote << ")')" << '\n';
  }
  f_remote << indent_str() << "print('')" << '\n' << indent_str() << "sys.exit(0)" << '\n' << '\n';

  f_remote << "pp = pprint.PrettyPrinter(indent=2)" << '\n'
           << "host = 'localhost'" << '\n'
           << "port = 9090" << '\n'
           << "uri = ''" << '\n'
           << "framed = False" << '\n'
           << "ssl = False" << '\n'
           << "validate = True" << '\n'
           << "ca_certs = None" << '\n'
           << "keyfile = None" << '\n'
           << "certfile = None" << '\n'
           << "http = False" << '\n'
           << "argi = 1" << '\n'
           << '\n'
           << "if sys.argv[argi] == '-h':" << '\n'
           << indent_str() << "parts = sys.argv[argi + 1].split(':')" << '\n'
           << indent_str() << "host = parts[0]" << '\n'
           << indent_str() << "if len(parts) > 1:" << '\n'
           << indent_str() << indent_str() << "port = int(parts[1])" << '\n'
           << indent_str() << "argi += 2" << '\n'
           << '\n'
           << "if sys.argv[argi] == '-u':" << '\n'
           << indent_str() << "url = urlparse(sys.argv[argi + 1])" << '\n'
           << indent_str() << "parts = url[1].split(':')" << '\n'
           << indent_str() << "host = parts[0]" << '\n'
           << indent_str() << "if len(parts) > 1:" << '\n'
           << indent_str() << indent_str() << "port = int(parts[1])" << '\n'
           << indent_str() << "else:" << '\n'
           << indent_str() << indent_str() << "port = 80" << '\n'
           << indent_str() << "uri = url[2]" << '\n'
           << indent_str() << "if url[4]:" << '\n'
           << indent_str() << indent_str() << "uri += '?%s' % url[4]" << '\n'
           << indent_str() << "http = True" << '\n'
           << indent_str() << "argi += 2" << '\n'
           << '\n'
           << "if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':" << '\n'
           << indent_str() << "framed = True" << '\n'
           << indent_str() << "argi += 1" << '\n'
           << '\n'
           << "if sys.argv[argi] == '-s' or sys.argv[argi] == '-ssl':" << '\n'
           << indent_str() << "ssl = True" << '\n'
           << indent_str() << "argi += 1" << '\n'
           << '\n'
           << "if sys.argv[argi] == '-novalidate':" << '\n'
           << indent_str() << "validate = False" << '\n'
           << indent_str() << "argi += 1" << '\n'
           << '\n'
           << "if sys.argv[argi] == '-ca_certs':" << '\n'
           << indent_str() << "ca_certs = sys.argv[argi+1]" << '\n'
           << indent_str() << "argi += 2" << '\n'
           << '\n'
           << "if sys.argv[argi] == '-keyfile':" << '\n'
           << indent_str() << "keyfile = sys.argv[argi+1]" << '\n'
           << indent_str() << "argi += 2" << '\n'
           << '\n'
           << "if sys.argv[argi] == '-certfile':" << '\n'
           << indent_str() << "certfile = sys.argv[argi+1]" << '\n'
           << indent_str() << "argi += 2" << '\n'
           << '\n'
           << "cmd = sys.argv[argi]" << '\n'
           << "args = sys.argv[argi + 1:]" << '\n'
           << '\n'
           << "if http:" << '\n'
           << indent_str() << "transport = THttpClient.THttpClient(host, port, uri)" << '\n'
           << "else:" << '\n'
           << indent_str() << "if ssl:" << '\n'
           << indent_str() << indent_str() << "socket = TSSLSocket.TSSLSocket(host, port, "
              "validate=validate, ca_certs=ca_certs, keyfile=keyfile, certfile=certfile)"
           << '\n'
           << indent_str() << "else:" << '\n'
           << indent_str() << indent_str() << "socket = TSocket.TSocket(host, port)" << '\n'
           << indent_str() << "if framed:" << '\n'
           << indent_str() << indent_str() << "transport = TTransport.TFramedTransport(socket)" << '\n'
           << indent_str() << "else:" << '\n'
           << indent_str() << indent_str() << "transport = TTransport.TBufferedTransport(socket)" << '\n'
           << "protocol = TBinaryProtocol(transport)" << '\n'
           << "client = " << service_name_ << ".Client(protocol)" << '\n'
           << "transport.open()" << '\n'
           << '\n';

  // Generate the dispatch methods
  bool first = true;

  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
    if (first) {
      first = false;
    } else {
      f_remote << "el";
    }

    t_struct* arg_struct = (*f_iter)->get_arglist();
    const std::vector<t_field*>& args = arg_struct->get_members();
    std::vector<t_field*>::size_type num_args = args.size();

    f_remote << "if cmd == '" << (*f_iter)->get_name() << "':" << '\n';
    indent_up();
    f_remote << indent() << "if len(args) != " << num_args << ":" << '\n'
             << indent() << indent_str() << "print('" << (*f_iter)->get_name() << " requires " << num_args
             << " args')" << '\n'
             << indent() << indent_str() << "sys.exit(1)" << '\n'
             << indent() << "pp.pprint(client." << (*f_iter)->get_name() << "(";
    indent_down();
    bool first_arg = true;
    for (std::vector<t_field*>::size_type i = 0; i < num_args; ++i) {
      if (first_arg)
        first_arg = false;
      else
        f_remote << " ";
      if (args[i]->get_type()->is_string()) {
        f_remote << "args[" << i << "],";
      } else {
        f_remote << "eval(args[" << i << "]),";
      }
    }
    f_remote << "))" << '\n';

    f_remote << '\n';
  }

  if (functions.size() > 0) {
    f_remote << "else:" << '\n';
    f_remote << indent_str() << "print('Unrecognized method %s' % cmd)" << '\n';
    f_remote << indent_str() << "sys.exit(1)" << '\n';
    f_remote << '\n';
  }

  f_remote << "transport.close()" << '\n';

  // Close service file
  f_remote.close();

#ifndef _MSC_VER

  // Make file executable, love that bitwise OR action
  chmod(f_remote_name.c_str(),
        S_IRUSR | S_IWUSR | S_IXUSR
#ifndef _WIN32
        | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
#endif
        );

#endif // _MSC_VER
}