text:
require "subscribem/constraints/subdomain_required"

Subscribem::Engine.routes.draw do
  constraints(Subscribem::Constraints::SubdomainRequired) do
    scope :module => "account" do
      root :to => "dashboard#index", :as => :account_root
      get "/sign_in", :to => "sessions#new"
      post "/sign_in", :to => "sessions#create", :as => :sessions
    end
  end

  root "dashboard#index"
  get '/sign_up', :to => "accounts#new", :as => :sign_up
  post '/accounts', :to => "accounts#create", :as => :accounts
end


text:
#ifndef _SLG_OUTPUTSWITCHER_PLUGIN_H
#define	_SLG_OUTPUTSWITCHER_PLUGIN_H

#include <vector>
#include <memory>
#include <typeinfo>
#include <boost/serialization/version.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/vector.hpp>

#include "luxrays/luxrays.h"
#include "luxrays/core/color/color.h"
#include "slg/film/imagepipeline/imagepipeline.h"

namespace slg {

//------------------------------------------------------------------------------
// OutputSwitcher plugin
//------------------------------------------------------------------------------

class OutputSwitcherPlugin : public ImagePipelinePlugin {
public:
	OutputSwitcherPlugin(const Film::FilmChannelType t, const u_int i) : type(t), index(i) { }
	virtual ~OutputSwitcherPlugin() { }

	virtual ImagePipelinePlugin *Copy() const;

	virtual void Apply(const Film &film, luxrays::Spectrum *pixels, std::vector<bool> &pixelsMask) const;

	Film::FilmChannelType type;
	u_int index;

	friend class boost::serialization::access;

private:
	// Used by serialization
	OutputSwitcherPlugin() { }

	template<class Archive> void serialize(Archive &ar, const u_int version) {
		ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(ImagePipelinePlugin);
		ar & type;
		ar & index;
	}
};

}

BOOST_CLASS_VERSION(slg::OutputSwitcherPlugin, 1)

BOOST_CLASS_EXPORT_KEY(slg::OutputSwitcherPlugin)

#endif	/*  _SLG_OUTPUTSWITCHER_PLUGIN_H */

redpajama_set_name: RedPajamaGithub


text:
package com.mikepenz.itemanimators;

import androidx.core.view.ViewCompat;
import androidx.core.view.ViewPropertyAnimatorCompat;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;

/**
 * Created by mikepenz on 08.01.16.
 * Base for this animator thanks to @gabrielemariotti - https://github.com/gabrielemariotti/RecyclerViewItemAnimators
 */
public class SlideInOutLeftAnimator extends DefaultAnimator<SlideInOutLeftAnimator> {

    private float mDeltaX;
    private RecyclerView mRecyclerView;

    public SlideInOutLeftAnimator(RecyclerView recyclerView) {
        mRecyclerView = recyclerView;
    }

    @Override
    public void addAnimationPrepare(RecyclerView.ViewHolder holder) {
        retrieveItemPosition(holder);
        ViewCompat.setTranslationX(holder.itemView, -mDeltaX);
        ViewCompat.setTranslationZ(holder.itemView, 100);
    }

    @Override
    public ViewPropertyAnimatorCompat addAnimation(RecyclerView.ViewHolder holder) {
        final View view = holder.itemView;
        return ViewCompat.animate(view).translationX(0).alpha(1).setDuration(getAddDuration());
    }

    @Override
    public void addAnimationCleanup(RecyclerView.ViewHolder holder) {
        ViewCompat.setAlpha(holder.itemView, 1);
        ViewCompat.setTranslationX(holder.itemView, 0);
        ViewCompat.setTranslationZ(holder.itemView, 1);
    }

    @Override
    public ViewPropertyAnimatorCompat removeAnimation(RecyclerView.ViewHolder holder) {
        ViewCompat.setTranslationZ(holder.itemView, 100);
        final ViewPropertyAnimatorCompat animation = ViewCompat.animate(holder.itemView);
        return animation.setDuration(getRemoveDuration()).alpha(0).translationX(-mDeltaX);
    }

    @Override
    public void removeAnimationCleanup(RecyclerView.ViewHolder holder) {
        ViewCompat.setTranslationX(holder.itemView, 0);
        ViewCompat.setAlpha(holder.itemView, 1);
        ViewCompat.setTranslationZ(holder.itemView, 1);
    }

    private void retrieveItemPosition(final RecyclerView.ViewHolder holder) {
        mDeltaX = mRecyclerView.getWidth() - mRecyclerView.getLayoutManager().getDecoratedLeft(holder.itemView);
    }

    @Override
    public long getAddDelay(long remove, long move, long change) {
        return 0;
    }

    @Override
    public long getRemoveDelay(long remove, long move, long change) {
        return remove / 2;
    }

}


text:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package kroki.app.action;

import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JDialog;
import kroki.app.KrokiMockupToolApp;
import kroki.app.gui.dialog.NewPackageDialog;
import kroki.app.utils.StringResource;
import kroki.profil.subsystem.BussinesSubsystem;

/**
 *
 * @author Vladan Marsenić (vladan.marsenic@gmail.com)
 */
public class NewPackageAction extends AbstractAction {

    BussinesSubsystem bussinesSubsystem;

    public NewPackageAction(BussinesSubsystem bussinesSubsystem) {
        this.bussinesSubsystem = bussinesSubsystem;
        putValue(NAME, StringResource.getStringResource("action.newPackage.name"));
        putValue(SHORT_DESCRIPTION, StringResource.getStringResource("action.newPackage.description"));
    }

    public NewPackageAction() {
        putValue(NAME, StringResource.getStringResource("action.newPackage.name"));
        putValue(SHORT_DESCRIPTION, StringResource.getStringResource("action.newPackage.description"));
    }

    public void actionPerformed(ActionEvent e) {
        NewPackageDialog dialog = new NewPackageDialog(KrokiMockupToolApp.getInstance().getKrokiMockupToolFrame(), bussinesSubsystem);
        dialog.setModal(true);
        dialog.pack();
        dialog.setLocationRelativeTo(null);
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.setVisible(true);
        KrokiMockupToolApp.getInstance().getKrokiMockupToolFrame().getTree().updateUI();
    }
}


text:
require 'renegade/version'

# Renegade module
module Renegade
end


text:
int main() {
    using namespace std;
    using namespace std::chrono;

    // Create pipeline
    dai::Pipeline pipeline;

    // Define sources and outputs
    auto camRgb = pipeline.create<dai::node::ColorCamera>();
    auto aprilTag = pipeline.create<dai::node::AprilTag>();
    auto manip = pipeline.create<dai::node::ImageManip>();

    auto xoutAprilTag = pipeline.create<dai::node::XLinkOut>();
    auto xoutAprilTagImage = pipeline.create<dai::node::XLinkOut>();

    xoutAprilTag->setStreamName("aprilTagData");
    xoutAprilTagImage->setStreamName("aprilTagImage");

    // Properties
    camRgb->setResolution(dai::ColorCameraProperties::SensorResolution::THE_1080_P);
    camRgb->setBoardSocket(dai::CameraBoardSocket::RGB);

    manip->initialConfig.setResize(480, 270);
    manip->initialConfig.setFrameType(dai::ImgFrame::Type::GRAY8);

    aprilTag->initialConfig.setFamily(dai::AprilTagConfig::Family::TAG_36H11);

    // Linking
    aprilTag->passthroughInputImage.link(xoutAprilTagImage->input);
    camRgb->video.link(manip->inputImage);
    manip->out.link(aprilTag->inputImage);
    aprilTag->out.link(xoutAprilTag->input);
    // always take the latest frame as apriltag detections are slow
    aprilTag->inputImage.setBlocking(false);
    aprilTag->inputImage.setQueueSize(1);

    // Connect to device and start pipeline
    dai::Device device(pipeline);

    // Output queue will be used to get the mono frames from the outputs defined above
    auto manipQueue = device.getOutputQueue("aprilTagImage", 8, false);
    auto aprilTagQueue = device.getOutputQueue("aprilTagData", 8, false);

    auto color = cv::Scalar(0, 255, 0);

    auto startTime = steady_clock::now();
    int counter = 0;
    float fps = 0;

    while(true) {
        auto inFrame = manipQueue->get<dai::ImgFrame>();

        counter++;
        auto currentTime = steady_clock::now();
        auto elapsed = duration_cast<duration<float>>(currentTime - startTime);
        if(elapsed > seconds(1)) {
            fps = counter / elapsed.count();
            counter = 0;
            startTime = currentTime;
        }

        cv::Mat monoFrame = inFrame->getFrame();
        cv::Mat frame;
        cv::cvtColor(monoFrame, frame, cv::COLOR_GRAY2BGR);

        auto aprilTagData = aprilTagQueue->get<dai::AprilTags>()->aprilTags;
        for(auto aprilTag : aprilTagData) {
            auto& topLeft = aprilTag.topLeft;
            auto& topRight = aprilTag.topRight;
            auto& bottomRight = aprilTag.bottomRight;
            auto& bottomLeft = aprilTag.bottomLeft;

            cv::Point center = cv::Point((topLeft.x + bottomRight.x) / 2, (topLeft.y + bottomRight.y) / 2);

            cv::line(frame, cv::Point(topLeft.x, topLeft.y), cv::Point(topRight.x, topRight.y), color, 2, cv::LINE_AA, 0);
            cv::line(frame, cv::Point(topRight.x, topRight.y), cv::Point(bottomRight.x, bottomRight.y), color, 2, cv::LINE_AA, 0);
            cv::line(frame, cv::Point(bottomRight.x, bottomRight.y), cv::Point(bottomLeft.x, bottomLeft.y), color, 2, cv::LINE_AA, 0);
            cv::line(frame, cv::Point(bottomLeft.x, bottomLeft.y), cv::Point(topLeft.x, topLeft.y), color, 2, cv::LINE_AA, 0);

            std::stringstream idStr;
            idStr << "ID: " << aprilTag.id;
            cv::putText(frame, idStr.str(), center, cv::FONT_HERSHEY_TRIPLEX, 0.5, color);
        }

        std::stringstream fpsStr;
        fpsStr << "fps:" << std::fixed << std::setprecision(2) << fps;
        cv::putText(frame, fpsStr.str(), cv::Point(2, inFrame->getHeight() - 4), cv::FONT_HERSHEY_TRIPLEX, 0.4, color);

        cv::imshow("April tag frame", frame);

        int key = cv::waitKey(1);
        if(key == 'q') {
            return 0;
        }
    }
    return 0;
}


text:
layout: page
title: Red Productions Dinner
date: 2016-05-24
author: Christopher Phelps
tags: weekly links, java
status: published
summary: Maecenas vestibulum nulla in blandit efficitur. Praesent laoreet ultrices tortor.
banner: images/banner/leisure-04.jpg
booking:
  startDate: 07/23/2016
  endDate: 07/27/2016
  ctyhocn: OKCNEHX
  groupCode: RPD
published: true
---
Vestibulum sit amet rutrum velit. Pellentesque faucibus tellus in imperdiet scelerisque. In consequat orci et ipsum malesuada, quis accumsan risus cursus. Sed a erat eget velit volutpat volutpat. Praesent vitae pulvinar libero. In tempor dignissim magna vel congue. Cras euismod faucibus sapien sed venenatis. Maecenas sagittis a magna lobortis feugiat. Curabitur efficitur consequat convallis. Duis ut neque et massa lacinia viverra vitae eget risus. Nunc posuere, sapien et imperdiet tincidunt, enim orci convallis diam, ac tempor neque augue id urna. Integer leo mauris, tristique non fringilla et, lacinia id odio. Nulla rutrum laoreet vehicula. Nullam vel volutpat orci. Nam nec lectus in metus dapibus tincidunt. Mauris a convallis felis.

1 Pellentesque sed est ultrices sem bibendum sollicitudin nec non neque
1 Maecenas eget leo in massa tempus semper.

Aliquam sit amet sagittis risus. Integer et sapien erat. Aliquam varius dolor non lacinia viverra. Vestibulum pellentesque tortor vel quam commodo, ac sagittis ex luctus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam volutpat maximus ex, vel convallis sem semper in. Maecenas et nunc est.
Suspendisse lacinia odio non laoreet vulputate. In hac habitasse platea dictumst. Cras non tortor vitae dolor mollis eleifend. Ut sit amet ipsum at nisi bibendum venenatis. Nullam faucibus, risus in rhoncus dictum, nisl tellus condimentum sem, nec feugiat nisi odio nec odio. Ut euismod lectus eget nunc tincidunt elementum. Nam consequat id libero quis gravida. Suspendisse ut lacinia eros, non suscipit nisl. Ut vestibulum, lorem eu dignissim ornare, diam urna ornare odio, eget rhoncus ex elit vitae velit.


text:
package org.jivesoftware.spark.uri;

import java.net.URI;

import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.spark.ChatManager;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.UserManager;
import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.ui.conferences.ConferenceUtils;

/**
 * Class to handle URI-Mappings defined by

 *
 * XEP-0147: XMPP URI Scheme
 * Query Components
 *
 * @author wolf.posdorfer
 *
 */
public class UriManager {

    public enum uritypes {
	message("message"),
	join("join"),
	unsubscribe("unsubscribe"),
	subscribe("subscribe"),
	roster("roster"),
	remove("remove");

	private String _xml;

	private uritypes(String s) {
	    _xml = s;
	}
	public String getXML() {
	    return _xml;
	}
    }

    /**
     * handles the ?message URI
     *
     * @param uri
     *            the decoded uri
     */
    public void handleMessage(URI uri) {

	String query = uri.getQuery();
	int bodyIndex = query.indexOf("body=");

	String jid = retrieveJID(uri);
	String body = null;

	// Find body
	if (bodyIndex != -1) {
	    body = query.substring(bodyIndex + 5);
	}

	body = org.jivesoftware.spark.util.StringUtils.unescapeFromXML(body);

	UserManager userManager = SparkManager.getUserManager();
	String nickname = userManager.getUserNicknameFromJID(jid);
	if (nickname == null) {
	    nickname = jid;
	}

	ChatManager chatManager = SparkManager.getChatManager();
	ChatRoom chatRoom = chatManager.createChatRoom(jid, nickname, nickname);
	if (body != null) {
	    Message message = new Message();
	    message.setBody(body);
	    chatRoom.sendMessage(message);
	}

	chatManager.getChatContainer().activateChatRoom(chatRoom);
    }

    /**
     * Handles the ?join URI
     *
     * @param uri
     *            the decoded uri
     * @throws Exception
     *             thrown if the conference cannot be joined.
     */
    public void handleConference(URI uri) throws Exception {
	String jid = retrieveJID(uri);
	ConferenceUtils.joinConferenceOnSeperateThread(jid, jid, null);
    }

    /**
     * Handles the ?subscribe URI
     *
     * @param uri
     *            the decoded uri
     * @throws Exception
     */
    public void handleSubscribe(URI uri) throws Exception {
	// xmpp:romeo@montague.net?subscribe
	// Send contact add request
	String jid = retrieveJID(uri);

	Presence response = new Presence(Presence.Type.subscribe);
	response.setTo(jid);
	SparkManager.getConnection().sendPacket(response);
    }

    /**
     * Handles the ?unsubscribe URI
     *
     * @param uri
     *            the decoded uri
     */
    public void handleUnsubscribe(URI uri) {
	String jid = retrieveJID(uri);

	Presence response = new Presence(Presence.Type.unsubscribe);
	response.setTo(jid);
	SparkManager.getConnection().sendPacket(response);
    }

    /***
     * Handles the ?roster URI

     * with name= and group=
     *
     * @param uri
     *            the decoded uri
     * @throws Exception
     */
    public void handleRoster(URI uri) throws Exception {
	// xmpp:romeo@montague.net?roster
	// xmpp:romeo@montague.net?roster;name=Romeo%20Montague
	// xmpp:romeo@montague.net?roster;group=Friends
	// xmpp:romeo@montague.net?roster;name=Romeo%20Montague;group=Friends
	String jid = retrieveJID(uri);

	String name = "";
	String query = uri.getQuery();
	if (query.contains("name=")) {
	    StringBuffer buf = new StringBuffer();
	    int x = query.indexOf("name=") + 5;
	    while (x < query.length() && query.charAt(x) != ';') {
		buf.append(query.charAt(x));
		x++;
	    }
	}
	String group = "";
	if (query.contains("group=")) {
	    StringBuffer buf = new StringBuffer();
	    int x = query.indexOf("group=") + 6;
	    while (x < query.length() && query.charAt(x) != ';') {
		buf.append(query.charAt(x));
		x++;
	    }
	}

	Roster roster = SparkManager.getConnection().getRoster();
	RosterEntry userEntry = roster.getEntry(jid);

	roster.createEntry(jid, name, new String[] { group });

	RosterGroup rosterGroup = roster.getGroup(group);
	if (rosterGroup == null) {
	    rosterGroup = roster.createGroup(group);
	}

	if (userEntry == null) {
	    roster.createEntry(jid, name, new String[] { group });
	    userEntry = roster.getEntry(jid);
	} else {
	    userEntry.setName(name);
	    rosterGroup.addEntry(userEntry);
	}

	userEntry = roster.getEntry(jid);

    }

    /**
     * Handles the ?remove URI
     *
     * @param uri
     *            the decoded uri
     * @throws Exception
     */
    public void handleRemove(URI uri) throws Exception {
	// xmpp:romeo@montague.net?remove

	String jid = retrieveJID(uri);
	Roster roster = SparkManager.getConnection().getRoster();
	RosterEntry entry = roster.getEntry(jid);
	roster.removeEntry(entry);
    }

    /**
     * Gets JID from URI. Returns the full jid including resource
     *
     * @param uri
     *            the URI
     * @return romeo@montague.net
     */
    public String retrieveJID(URI uri) {
	StringBuilder sb = new StringBuilder(32);
	String user = uri.getUserInfo();
	if (user != null) {
	    sb.append(user);
	    sb.append('@');
	}
	sb.append(uri.getHost());
	// Resource contains the leading /
	String resource = uri.getPath();
	if (resource != null && resource.length() > 0 && !resource.equals("/")) {
	    sb.append(resource);
	}
	return sb.toString();
    }
}


text:
package com.mycompany.myapp.config;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;

import com.mycompany.myapp.GeneratedByJHipster;
import com.mycompany.myapp.service.MailService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@GeneratedByJHipster
public class NoOpMailConfiguration {

    private final MailService mockMailService;

    public NoOpMailConfiguration() {
        mockMailService = mock(MailService.class);
        doNothing().when(mockMailService).sendActivationEmail(any());
    }

    @Bean
    public MailService mailService() {
        return mockMailService;
    }
}


text:
package org.zalando.intellij.swagger.completion;

import com.intellij.util.net.HTTPMethod;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.zalando.intellij.swagger.fixture.SwaggerFixture.JsonOrYaml;

import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Collectors;

@RunWith(Parameterized.class)
public class CaretCompletionTest extends AbstractJsonOrYamlCompletionTest {
    public CaretCompletionTest(JsonOrYaml jsonOrYaml) {
        super(jsonOrYaml);
    }

    @Parameterized.Parameters(name = "inputKind: {0}")
    public static Object[] parameters() {
        return JsonOrYaml.values();
    }

    @Before
    public void setUpBefore() throws Exception {
        useResourceFolder("testing/completion");
    }

    @Test
    public void thatRootKeyIsCompleted() {
        getCaretCompletions("top_level")
                .assertContains("basePath", "produces", "consumes", "schemes",
                        "paths", "tags", "parameters", "responses")
                .assertNotContains("head", "get", "post", "operationId");
    }

    @Test
    public void thatExistingKeysAreNotShown() {
        getCaretCompletions("top_level").assertNotContains("swagger", "host");
    }

    @Test
    public void testGlobalConsumes() {
        getCaretCompletions("media_type_consumes")
                .assertContains("application/xml", "image/*", "text/plain")
                .assertNotContains("consumes", "produces", "paths");
    }

    @Test
    public void testGlobalProduces() {
        getCaretCompletions("media_type_produces")
                .assertNotContains("consumes", "produces", "paths")
                .assertContains("application/xml", "image/*", "text/plain");
    }

    @Test
    public void testHttpOperations() {
        //see swagger spec, all but 'trace' operations are supported
        Collection<String> allButTrace = Arrays.stream(HTTPMethod.values())
                .filter(m -> m != HTTPMethod.TRACE)
                .map(HTTPMethod::name)
                .map(String::toLowerCase)
                .sorted()
                .collect(Collectors.toList());

        getCaretCompletions("http_operations")
                .assertContains(allButTrace)
                .assertContains("$ref")
                .assertNotContains("trace");
    }

    @Test
    public void testRefValue() throws Exception {
        getCaretCompletions("ref_value")
                .assertContains("#/definitions/Pets", "#/definitions/Error")
                .isOfSize(2);
    }

    @Ignore("See issue #30")
    @Test
    public void enumValuesCompletion_ParametersIn() {
        getCaretCompletions("enum_parameters_in")
                .assertContains("path", "header", "query", "formData", "body");
    }

    @Ignore("See issue #21")
    @Test
    public void booleanValuesCompletion_ParametersRequired() {
        getCaretCompletions("boolean_parameters_required")
                .assertContains("true", "false");
    }

}


text:
// flow-typed signature: c3f86ee28eceff91615bfdc522f239e1
// flow-typed version: <<STUB>>/babel-plugin-transform-regenerator_v^6.9.0/flow_v0.33.0

/**
 * This is an autogenerated libdef stub for:
 *
 *   'babel-plugin-transform-regenerator'
 *
 * Fill this stub out by replacing all the `any` types.
 *
 * Once filled out, we encourage you to share your work with the
 * community by sending a pull request to:
 * https://github.com/flowtype/flow-typed
 */

declare module 'babel-plugin-transform-regenerator' {
  declare module.exports: any;
}

/**
 * We include stubs for each file inside this npm package in case you need to
 * require those files directly. Feel free to delete any files that aren't
 * needed.
 */
declare module 'babel-plugin-transform-regenerator/lib/emit' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/lib/hoist' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/lib/index' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/lib/leap' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/lib/meta' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/lib/util' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/lib/visit' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/src/emit' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/src/hoist' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/src/index' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/src/leap' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/src/meta' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/src/util' {
  declare module.exports: any;
}

declare module 'babel-plugin-transform-regenerator/src/visit' {
  declare module.exports: any;
}

// Filename aliases
declare module 'babel-plugin-transform-regenerator/lib/emit.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/lib/emit'>;
}
declare module 'babel-plugin-transform-regenerator/lib/hoist.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/lib/hoist'>;
}
declare module 'babel-plugin-transform-regenerator/lib/index.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/lib/index'>;
}
declare module 'babel-plugin-transform-regenerator/lib/leap.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/lib/leap'>;
}
declare module 'babel-plugin-transform-regenerator/lib/meta.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/lib/meta'>;
}
declare module 'babel-plugin-transform-regenerator/lib/util.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/lib/util'>;
}
declare module 'babel-plugin-transform-regenerator/lib/visit.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/lib/visit'>;
}
declare module 'babel-plugin-transform-regenerator/src/emit.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/src/emit'>;
}
declare module 'babel-plugin-transform-regenerator/src/hoist.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/src/hoist'>;
}
declare module 'babel-plugin-transform-regenerator/src/index.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/src/index'>;
}
declare module 'babel-plugin-transform-regenerator/src/leap.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/src/leap'>;
}
declare module 'babel-plugin-transform-regenerator/src/meta.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/src/meta'>;
}
declare module 'babel-plugin-transform-regenerator/src/util.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/src/util'>;
}
declare module 'babel-plugin-transform-regenerator/src/visit.js' {
  declare module.exports: $Exports<'babel-plugin-transform-regenerator/src/visit'>;
}


text:
#include <Python.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "fdfs_client.h"
#include "fdfs_global.h"
#include "base64.h"
#include "sockopt.h"
#include "logger.h"
#include "fdfs_http_shared.h"

#define FDFSPYMOD "fdfspyclient"

static int writeToFileCallback(void *arg, const int64_t file_size,
			       const char *data, const int current_size);
static int uploadFileCallback(void *arg, const int64_t file_size,
			      int sock);
static int list_storages(ConnectionInfo * pTrackerServer,
			 FDFSGroupStat * pGroupStat);
static int list_all_groups(ConnectionInfo * pTrackerServer,
			   const char *group_name);

static PyObject *fdfs_init(PyObject * self, PyObject * args)
{
	int result;
	char *conf_filename;
	if (!PyArg_ParseTuple(args, "s", &conf_filename)) {
		printf("usage: " FDFSPYMOD ".fdfs_init(conf_filename)\n");
		return NULL;
	}

	log_init();
	g_log_context.log_level = LOG_DEBUG;

	result = fdfs_client_init(conf_filename);

	return Py_BuildValue("i", result);
}

static PyObject *fdfs_upload(PyObject * self, PyObject * args)
{
	char *local_filename;
	char *upload_typestr;
	ConnectionInfo *pTrackerServer;
	ConnectionInfo *pStorageServer;
	int result;
	ConnectionInfo storageServer;
	char group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
	char remote_filename[256];
	FDFSMetaData meta_list[32];
	int meta_count;
	char token[32 + 1];
	char file_id[128];
	char file_url[256];
	char szPortPart[16];
	int url_len;
	time_t ts;
	int64_t file_size;
	int store_path_index;

	if (!PyArg_ParseTuple
	    (args, "sz", &local_filename, &upload_typestr)) {
		printf("usage: " FDFSPYMOD
		       ".fdfs_upload(local_filename, upload_typestr | None)\n");
		fdfs_client_destroy();
		return NULL;
	}

	pTrackerServer = tracker_get_connection();
	if (pTrackerServer == NULL) {
		fdfs_client_destroy();
		result = errno != 0 ? errno : ECONNREFUSED;
		return Py_BuildValue("i", result);
	}

	pStorageServer = NULL;
	*group_name = '\0';

	int upload_type;
	const char *file_ext_name;

	if (upload_typestr == NULL) {
		upload_type = FDFS_UPLOAD_BY_FILE;
	} else if (strcmp(upload_typestr, "BUFF") == 0) {
		upload_type = FDFS_UPLOAD_BY_BUFF;
	} else if (strcmp(upload_typestr, "CALLBACK") == 0) {
		upload_type = FDFS_UPLOAD_BY_CALLBACK;
	} else {
		upload_type = FDFS_UPLOAD_BY_FILE;
	}

	store_path_index = 0;

	{
		ConnectionInfo storageServers[FDFS_MAX_SERVERS_EACH_GROUP];
		int storage_count;

		tracker_query_storage_store_list_without_group
		    (pTrackerServer, storageServers,
		     FDFS_MAX_SERVERS_EACH_GROUP, &storage_count,
		     group_name, &store_path_index);
	}

	if ((result = tracker_query_storage_store(pTrackerServer,
						  &storageServer,
						  group_name,
						  &store_path_index))
	    != 0) {
		fdfs_client_destroy();
		printf("tracker_query_storage fail, "
		       "error no: %d, error info: %s\n",
		       result, STRERROR(result));
		return Py_BuildValue("i", result);
	}

	if ((pStorageServer =
	     tracker_connect_server(&storageServer, &result)) == NULL) {
		fdfs_client_destroy();
		return Py_BuildValue("i", result);
	}

	memset(&meta_list, 0, sizeof(meta_list));
	meta_count = 0;
	strcpy(meta_list[meta_count].name, "ext_name");
	strcpy(meta_list[meta_count].value, "jpg");
	meta_count++;
	strcpy(meta_list[meta_count].name, "width");
	strcpy(meta_list[meta_count].value, "160");
	meta_count++;
	strcpy(meta_list[meta_count].name, "height");
	strcpy(meta_list[meta_count].value, "80");
	meta_count++;
	strcpy(meta_list[meta_count].name, "file_size");
	strcpy(meta_list[meta_count].value, "115120");
	meta_count++;

	file_ext_name = fdfs_get_file_ext_name(local_filename);
	*group_name = '\0';

	if (upload_type == FDFS_UPLOAD_BY_FILE) {
		result = storage_upload_by_filename(pTrackerServer,
						    pStorageServer,
						    store_path_index,
						    local_filename,
						    file_ext_name,
						    meta_list,
						    meta_count,
						    group_name,
						    remote_filename);

	} else if (upload_type == FDFS_UPLOAD_BY_BUFF) {
		char *file_content;
		if ((result = getFileContent(local_filename,
					     &file_content,
					     &file_size)) == 0) {
			result =
			    storage_upload_by_filebuff
			    (pTrackerServer, pStorageServer,
			     store_path_index, file_content,
			     file_size, file_ext_name, meta_list,
			     meta_count, group_name, remote_filename);
			free(file_content);
		}

	} else {
		struct stat stat_buf;

		if (stat(local_filename, &stat_buf) == 0 &&
		    S_ISREG(stat_buf.st_mode)) {
			file_size = stat_buf.st_size;
			result =
			    storage_upload_by_callback
			    (pTrackerServer, pStorageServer,
			     store_path_index, uploadFileCallback,
			     local_filename, file_size,
			     file_ext_name, meta_list, meta_count,
			     group_name, remote_filename);
		}

	}

	if (result != 0) {
		printf("upload file fail, "
		       "error no: %d, error info: %s\n",
		       result, STRERROR(result));
		tracker_disconnect_server_ex(pStorageServer, true);
		fdfs_client_destroy();
		return Py_BuildValue("i", result);
	}

	if (g_tracker_server_http_port == 80) {
		*szPortPart = '\0';
	} else {
		sprintf(szPortPart, ":%d", g_tracker_server_http_port);
	}

	sprintf(file_id, "%s/%s", group_name, remote_filename);
	url_len = sprintf(file_url, "http://%s%s/%s",
			  pStorageServer->ip_addr, szPortPart, file_id);
	if (g_anti_steal_token) {
		ts = time(NULL);
		fdfs_http_gen_token(&g_anti_steal_secret_key,
				    file_id, ts, token);
		sprintf(file_url + url_len, "?token=%s&ts=%d",
			token, (int) ts);
	}

	tracker_disconnect_server_ex(pStorageServer, true);
	tracker_disconnect_server_ex(pTrackerServer, true);

	return Py_BuildValue("(i, s, s, s)", result, group_name,
			     remote_filename, file_url);
}

static PyObject *fdfs_download(PyObject * self, PyObject * args)
{
	char *local_filename;
	ConnectionInfo *pTrackerServer;
	ConnectionInfo *pStorageServer;
	int result;
	ConnectionInfo storageServer;
	char *group_name;
	char *remote_filename;
	char *file_buff;
	int64_t file_size;
	char filesizebuff[1024];

	if (!PyArg_ParseTuple
	    (args, "ssz", &group_name, &remote_filename,
	     &local_filename)) {
		printf("usage: " FDFSPYMOD
		       ".fdfs_download(group_name, remote_filename, local_filename | None)\n");
		fdfs_client_destroy();

		return NULL;
	}

	pTrackerServer = tracker_get_connection();
	if (pTrackerServer == NULL) {
		fdfs_client_destroy();
		result = errno != 0 ? errno : ECONNREFUSED;
		return Py_BuildValue("i", result);
	}

	pStorageServer = NULL;
	if ((result =
	     tracker_query_storage_fetch(pTrackerServer,
					 &storageServer,
					 group_name,
					 remote_filename)) != 0) {
		fdfs_client_destroy();
		printf("tracker_query_storage_fetch fail, "
		       "group_name=%s, filename=%s, "
		       "error no: %d, error info: %s\n",
		       group_name, remote_filename,
		       result, STRERROR(result));
		return Py_BuildValue("i", result);
	}

	if ((pStorageServer =
	     tracker_connect_server(&storageServer, &result)) == NULL) {
		fdfs_client_destroy();
		return Py_BuildValue("i", result);
	}

	if (local_filename != NULL) {
		if (strcmp(local_filename, "CALLBACK") == 0) {
			FILE *fp;
			fp = fopen(local_filename, "wb");
			if (fp == NULL) {
				result = errno != 0 ? errno : EPERM;
				printf
				    ("open file \"%s\" fail, "
				     "errno: %d, error info: %s",
				     local_filename,
				     result, STRERROR(result));
			} else {
				result =
				    storage_download_file_ex
				    (pTrackerServer,
				     pStorageServer,
				     group_name,
				     remote_filename, 0, 0,
				     writeToFileCallback, fp, &file_size);
				fclose(fp);
			}
		} else {
			result =
			    storage_download_file_to_file
			    (pTrackerServer,
			     pStorageServer, group_name,
			     remote_filename, local_filename, &file_size);
		}
	} else {
		file_buff = NULL;
		if ((result =
		     storage_download_file_to_buff
		     (pTrackerServer, pStorageServer,
		      group_name, remote_filename,
		      &file_buff, &file_size)) == 0) {
			local_filename = strrchr(remote_filename, '/');
			if (local_filename != NULL) {
				local_filename++;	//skip /
			} else {
				local_filename = remote_filename;
			}

			result =
			    writeToFile(local_filename,
					file_buff, file_size);

			free(file_buff);
		}
	}

	if (result == 0) {
		snprintf(filesizebuff, sizeof(filesizebuff), "%" PRId64,
			 file_size);
	} else {
		printf("download file fail, "
		       "error no: %d, error info: %s\n",
		       result, STRERROR(result));
	}
	tracker_disconnect_server_ex(pStorageServer, true);
	tracker_disconnect_server_ex(pTrackerServer, true);

	return Py_BuildValue("(i, s, s)", result, local_filename,
			     filesizebuff);
}

static PyObject *fdfs_delete(PyObject * self, PyObject * args)
{
	ConnectionInfo *pTrackerServer;
	ConnectionInfo *pStorageServer;
	int result;
	ConnectionInfo storageServer;
	char *group_name;
	char *remote_filename;

	if (!PyArg_ParseTuple(args, "ss", &group_name, &remote_filename)) {
		printf("usage: " FDFSPYMOD
		       ".fdfs_delete(group_name, remote_filename)\n");
		fdfs_client_destroy();

		return NULL;
	}

	pTrackerServer = tracker_get_connection();
	if (pTrackerServer == NULL) {
		fdfs_client_destroy();
		result = errno != 0 ? errno : ECONNREFUSED;
		return Py_BuildValue("i", result);
	}

	pStorageServer = NULL;

	result =
	    tracker_query_storage_update(pTrackerServer,
					 &storageServer,
					 group_name, remote_filename);
	if ((result =
	     tracker_query_storage_fetch(pTrackerServer,
					 &storageServer,
					 group_name,
					 remote_filename)) != 0) {
		fdfs_client_destroy();
		printf("tracker_query_storage_fetch fail, "
		       "group_name=%s, filename=%s, "
		       "error no: %d, error info: %s\n",
		       group_name, remote_filename,
		       result, STRERROR(result));
		return Py_BuildValue("i", result);
	}
	if ((pStorageServer =
	     tracker_connect_server(&storageServer, &result)) == NULL) {
		fdfs_client_destroy();
		return Py_BuildValue("i", result);
	}
	if ((result = storage_delete_file(pTrackerServer,
					  NULL, group_name,
					  remote_filename))
	    == 0) {
	} else {
		printf("delete file fail, "
		       "error no: %d, error info: %s\n",
		       result, STRERROR(result));
	}

	tracker_disconnect_server_ex(pStorageServer, true);
	tracker_disconnect_server_ex(pTrackerServer, true);

	return Py_BuildValue("i", result);
}

static PyObject *fdfs_getmeta(PyObject * self, PyObject * args)
{
	ConnectionInfo *pTrackerServer;
	ConnectionInfo *pStorageServer;
	int result;
	ConnectionInfo storageServer;
	char *group_name;
	char *remote_filename;
	int meta_count;
	int i;
	FDFSMetaData *pMetaList;
	PyObject *metatable = NULL;
	char kv[1024];

	if (!PyArg_ParseTuple(args, "ss", &group_name, &remote_filename)) {
		printf("usage: " FDFSPYMOD
		       ".fdfs_getmeta(group_name, remote_filename)\n");
		fdfs_client_destroy();

		return NULL;
	}

	pTrackerServer = tracker_get_connection();
	if (pTrackerServer == NULL) {
		fdfs_client_destroy();
		result = errno != 0 ? errno : ECONNREFUSED;
		return Py_BuildValue("i", result);
	}

	pStorageServer = NULL;
	result =
	    tracker_query_storage_fetch(pTrackerServer,
					&storageServer,
					group_name, remote_filename);

	if (result != 0) {
		fdfs_client_destroy();
		printf("tracker_query_storage_fetch fail, "
		       "group_name=%s, filename=%s, "
		       "error no: %d, error info: %s\n",
		       group_name, remote_filename,
		       result, STRERROR(result));
		return Py_BuildValue("i", result);
	}

	if ((pStorageServer =
	     tracker_connect_server(&storageServer, &result)) == NULL) {
		fdfs_client_destroy();
		return Py_BuildValue("i", result);
	}
	if ((result = storage_get_metadata(pTrackerServer,
					   pStorageServer,
					   group_name,
					   remote_filename,
					   &pMetaList,
					   &meta_count)) == 0) {
		metatable = PyTuple_New(meta_count);
		for (i = 0; i < meta_count; i++) {
			snprintf(kv, sizeof(kv), "%s=%s",
				 pMetaList[i].name, pMetaList[i].value);
			PyTuple_SetItem(metatable, i,
					PyString_FromString(kv));
		}

		free(pMetaList);
	} else {
		printf("getmeta fail, "
		       "error no: %d, error info: %s\n",
		       result, STRERROR(result));
	}

	tracker_disconnect_server_ex(pStorageServer, true);
	tracker_disconnect_server_ex(pTrackerServer, true);

	return Py_BuildValue("iiO", result, meta_count, metatable);
}

static PyObject *fdfs_setmeta(PyObject * self, PyObject * args)
{
	ConnectionInfo *pTrackerServer;
	ConnectionInfo *pStorageServer;
	int result;
	ConnectionInfo storageServer;
	char *group_name;
	char *remote_filename;
	int meta_count;
	FDFSMetaData *pMetaList;
	char *meta_buff;
	char *op_flag;

	if (!PyArg_ParseTuple
	    (args, "ssss", &group_name, &remote_filename, &op_flag,
	     &meta_buff)) {
		printf("usage: " FDFSPYMOD
		       ".fdfs_setmeta(group_name, remote_filename,"
		       " op_flag, metadata_list)\n"
		       "\top_flag: %c for overwrite, " "%c for merge\n"
		       "\tmetadata_list: name1=value1,"
		       "name2=value2,...\n",
		       STORAGE_SET_METADATA_FLAG_OVERWRITE,
		       STORAGE_SET_METADATA_FLAG_MERGE);

		fdfs_client_destroy();
		return NULL;
	}

	pTrackerServer = tracker_get_connection();
	if (pTrackerServer == NULL) {
		fdfs_client_destroy();
		result = errno != 0 ? errno : ECONNREFUSED;
		return Py_BuildValue("i", result);
	}

	pStorageServer = NULL;
	if ((result = tracker_query_storage_update(pTrackerServer,
						   &storageServer,
						   group_name,
						   remote_filename)) !=
	    0) {

		fdfs_client_destroy();
		printf("tracker_query_storage_fetch fail, "
		       "group_name=%s, filename=%s, "
		       "error no: %d, error info: %s\n",
		       group_name, remote_filename,
		       result, STRERROR(result));
		return Py_BuildValue("i", result);
	}

	if ((pStorageServer =
	     tracker_connect_server(&storageServer, &result)) == NULL) {
		fdfs_client_destroy();
		return Py_BuildValue("i", result);
	}
	pMetaList = fdfs_split_metadata_ex(meta_buff,
					   ',', '=', &meta_count, &result);
	if (pMetaList == NULL) {
		printf("Out of memory!\n");
		return Py_BuildValue("i", ENOMEM);
	}

	if ((result = storage_set_metadata(pTrackerServer,
					   NULL,
					   group_name,
					   remote_filename,
					   pMetaList,
					   meta_count, *op_flag)) == 0) {
	} else {
		printf("setmeta fail, "
		       "error no: %d, error info: %s\n",
		       result, STRERROR(result));
	}

	free(pMetaList);

	tracker_disconnect_server_ex(pStorageServer, true);
	tracker_disconnect_server_ex(pTrackerServer, true);

	return Py_BuildValue("i", result);
}

static PyObject *fdfs_query_servers(PyObject * self, PyObject * args)
{
	int result;
	char *group_name;
	char *remote_filename;
	ConnectionInfo *pTrackerServer;
	int i;
	ConnectionInfo storageServers[FDFS_MAX_SERVERS_EACH_GROUP];
	int server_count;
	char ip_port[80];
	PyObject *storageServertable = NULL;

	if (!PyArg_ParseTuple(args, "ss", &group_name, &remote_filename)) {
		printf("usage: " FDFSPYMOD
		       ".fdfs_query_servers(group_name, remote_filename)\n");
		fdfs_client_destroy();
		return NULL;
	}
	pTrackerServer = tracker_get_connection();
	if (pTrackerServer == NULL) {
		fdfs_client_destroy();
		result = errno != 0 ? errno : ECONNREFUSED;
		return Py_BuildValue("i", result);
	}

	result = tracker_query_storage_list(pTrackerServer,
					    storageServers,
					    FDFS_MAX_SERVERS_EACH_GROUP,
					    &server_count,
					    group_name, remote_filename);

	if (result != 0) {
		printf("tracker_query_storage_list fail, "
		       "group_name=%s, filename=%s, "
		       "error no: %d, error info: %s\n",
		       group_name, remote_filename,
		       result, STRERROR(result));
	} else {
		storageServertable = PyTuple_New(server_count);
		for (i = 0; i < server_count; i++) {
			snprintf(ip_port, sizeof(ip_port),
				 "ip:%s, port:%d",
				 storageServers[i].ip_addr,
				 storageServers[i].port);
			PyTuple_SetItem(storageServertable, i,
					PyString_FromString(ip_port));
		}
	}

	tracker_disconnect_server_ex(pTrackerServer, result != 0);

	return Py_BuildValue("iiO", result, server_count,
			     storageServertable);
}

static PyObject *fdfs_append_file(PyObject * self, PyObject * args)
{
	char *local_filename;
	ConnectionInfo *pTrackerServer;
	int result;
	char *appender_file_id;

	if (!PyArg_ParseTuple
	    (args, "ss", &appender_file_id, &local_filename)) {
		printf("usage: " FDFSPYMOD
		       ".fdfs_append_file(append_file_id, local_filename)\n"
		       "\tappend_file_id:groupname+remote_filename(ex:group1/M00/00/00/wKj_gVVjzBOAMy5EAAAD6VEwZK86469523)\n");
		fdfs_client_destroy();
		return NULL;
	}
	pTrackerServer = tracker_get_connection();
	if (pTrackerServer == NULL) {
		fdfs_client_destroy();
		result = errno != 0 ? errno : ECONNREFUSED;
		return Py_BuildValue("i", result);
	}

	if ((result = storage_append_by_filename1(pTrackerServer,
						  NULL, local_filename,
						  appender_file_id)) !=
	    0) {
		printf("append file fail, "
		       "error no: %d, error info: %s\n", result,
		       STRERROR(result));
		return Py_BuildValue("i", result);
	}

	tracker_disconnect_server_ex(pTrackerServer, true);

	return Py_BuildValue("i", result);
}

static PyObject *fdfs_file_info(PyObject * self, PyObject * args)
{
	char *file_id;
	int result;
	FDFSFileInfo file_info;
	PyObject *fileinfotable = NULL;
	char buff[1024];

	if (!PyArg_ParseTuple(args, "s", &file_id)) {
		printf("usage: " FDFSPYMOD ".fdfs_file_info(file_id)\n"
		       "\tappend_file_id:groupname+remote_filename(ex:group1/M00/00/00/wKj_gVVjzBOAMy5EAAAD6VEwZK86469523)\n");
		fdfs_client_destroy();
		return NULL;
	}

	ignore_signal_pipe();

	memset(&file_info, 0, sizeof(file_info));
	result = fdfs_get_file_info_ex1(file_id, true, &file_info);
	if (result != 0) {
		printf("query file info fail, "
		       "error no: %d, error info: %s\n",
		       result, STRERROR(result));
	} else {
		char szDatetime[32];

		fileinfotable = PyTuple_New(5);
		snprintf(buff, sizeof(buff), "source storageid: %d",
			 file_info.source_id);
		PyTuple_SetItem(fileinfotable, 0,
				PyString_FromString(buff));
		snprintf(buff, sizeof(buff), "source ip address: %s",
			 file_info.source_ip_addr);
		PyTuple_SetItem(fileinfotable, 1,
				PyString_FromString(buff));
		snprintf(buff, sizeof(buff), "file create timestamp: %s",
			 formatDatetime(file_info.create_timestamp,
					"%Y-%m-%d %H:%M:%S", szDatetime,
					sizeof(szDatetime)));
		PyTuple_SetItem(fileinfotable, 2,
				PyString_FromString(buff));
		snprintf(buff, sizeof(buff), "file size: %" PRId64 "",
			 file_info.file_size);
		PyTuple_SetItem(fileinfotable, 3,
				PyString_FromString(buff));
		snprintf(buff, sizeof(buff), "file crc32: %u (0x%08X)",
			 file_info.crc32, file_info.crc32);
		PyTuple_SetItem(fileinfotable, 4,
				PyString_FromString(buff));
	}

	tracker_close_all_connections();

	return Py_BuildValue("iO", result, fileinfotable);
}

static PyObject *fdfs_upload_append(PyObject * self, PyObject * args)
{
	char *local_filename;
	char group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
	ConnectionInfo *pTrackerServer;
	int result;
	int store_path_index;
	ConnectionInfo storageServer;
	char file_id[128];

	if (!PyArg_ParseTuple(args, "s", &local_filename)) {
		printf("usage: " FDFSPYMOD
		       ".fdfs_upload_append(local_filename)\n");
		fdfs_client_destroy();
		return NULL;
	}

	pTrackerServer = tracker_get_connection();
	if (pTrackerServer == NULL) {
		fdfs_client_destroy();
		result = errno != 0 ? errno : ECONNREFUSED;
		return Py_BuildValue("i", result);
	}

	store_path_index = 0;
	if ((result = tracker_query_storage_store(pTrackerServer,
						  &storageServer,
						  group_name,
						  &store_path_index)) !=
	    0) {
		fdfs_client_destroy();
		fprintf(stderr, "tracker_query_storage fail, "
			"error no: %d, error info: %s\n",
			result, STRERROR(result));
		return Py_BuildValue("i", result);
	}

	result = storage_upload_appender_by_filename1(pTrackerServer,
						      &storageServer,
						      store_path_index,
						      local_filename, NULL,
						      NULL, 0, group_name,
						      file_id);
	if (result != 0) {
		fprintf(stderr, "upload file fail, "
			"error no: %d, error info: %s\n",
			result, STRERROR(result));

		tracker_disconnect_server_ex(pTrackerServer, true);
		fdfs_client_destroy();
		return Py_BuildValue("i", result);
	}

	tracker_disconnect_server_ex(pTrackerServer, true);

	return Py_BuildValue("(i, s)", result, file_id);
}

static PyObject *fdfs_list_all_groups(PyObject * self, PyObject * args)
{
	ConnectionInfo *pTrackerServer;
	int result;
	char *tracker_server;
	char *group_name;

	if (!PyArg_ParseTuple(args, "zz", &tracker_server, &group_name)) {
		printf("usage: " FDFSPYMOD
		       ".fdfs_list_all_groups(tracker_server | None, group_name | None)\n");
		fdfs_client_destroy();
		return NULL;
	}

	if (tracker_server == NULL) {
		if (g_tracker_group.server_count > 1) {
			srand(time(NULL));
			rand();	//discard the first
			g_tracker_group.server_index =
			    (int) ((g_tracker_group.server_count *
				    (double) rand())
				   / (double)
				   RAND_MAX);
		}
	} else {
		int i;
		char ip_addr[IP_ADDRESS_SIZE];

		*ip_addr = '\0';
		if (getIpaddrByName
		    (tracker_server, ip_addr, sizeof(ip_addr))
		    == INADDR_NONE) {
			printf("resolve ip address of tracker server: %s "
			       "fail!\n", tracker_server);
			return Py_BuildValue("i", 2);
		}

		for (i = 0; i < g_tracker_group.server_count; i++) {
			if (strcmp(g_tracker_group.servers[i].ip_addr,
				   ip_addr) == 0) {
				g_tracker_group.server_index = i;
				break;
			}
		}

		if (i == g_tracker_group.server_count) {
			printf("tracker server: %s not exists!\n",
			       tracker_server);
			return Py_BuildValue("i", 2);
		}
	}

	pTrackerServer = tracker_get_connection();
	if (pTrackerServer == NULL) {
		fdfs_client_destroy();
		result = errno != 0 ? errno : ECONNREFUSED;
		return Py_BuildValue("i", result);
	}

	if (group_name == NULL) {
		result = list_all_groups(pTrackerServer, NULL);
	} else {
		result = list_all_groups(pTrackerServer, group_name);
	}

	tracker_disconnect_server_ex(pTrackerServer, true);

	return Py_BuildValue("i", result);
}

static PyObject *fdfs_delete_group(PyObject * self, PyObject * args)
{
	ConnectionInfo *pTrackerServer;
	int result;
	char *tracker_server;
	char *group_name;

	if (!PyArg_ParseTuple(args, "zs", &tracker_server, &group_name)) {
		printf("usage: " FDFSPYMOD
		       ".fdfs_delete_group(tracker_server | None, group_name)\n");
		fdfs_client_destroy();
		return NULL;
	}

	if (tracker_server == NULL) {
		if (g_tracker_group.server_count > 1) {
			srand(time(NULL));
			rand();	//discard the first
			g_tracker_group.server_index =
			    (int) ((g_tracker_group.server_count *
				    (double) rand())
				   / (double)
				   RAND_MAX);
		}
	} else {
		int i;
		char ip_addr[IP_ADDRESS_SIZE];

		*ip_addr = '\0';
		if (getIpaddrByName
		    (tracker_server, ip_addr, sizeof(ip_addr))
		    == INADDR_NONE) {
			printf("resolve ip address of tracker server: %s "
			       "fail!\n", tracker_server);
			return Py_BuildValue("i", 2);
		}

		for (i = 0; i < g_tracker_group.server_count; i++) {
			if (strcmp(g_tracker_group.servers[i].ip_addr,
				   ip_addr) == 0) {
				g_tracker_group.server_index = i;
				break;
			}
		}

		if (i == g_tracker_group.server_count) {
			printf("tracker server: %s not exists!\n",
			       tracker_server);
			return Py_BuildValue("i", 2);
		}
	}

	pTrackerServer = tracker_get_connection();
	if (pTrackerServer == NULL) {
		fdfs_client_destroy();
		result = errno != 0 ? errno : ECONNREFUSED;
		return Py_BuildValue("i", result);
	}

	if ((result =
	     tracker_delete_group(&g_tracker_group, group_name)) != 0) {
		printf("delete group: %s fail, "
		       "error no: %d, error info: %s\n",
		       group_name, result, STRERROR(result));
	}

	tracker_disconnect_server_ex(pTrackerServer, true);
	return Py_BuildValue("i", result);
}

static PyObject *fdfs_delete_server(PyObject * self, PyObject * args)
{
	ConnectionInfo *pTrackerServer;
	int result;
	char *tracker_server;
	char *storage_id;
	char *group_name;

	if (!PyArg_ParseTuple
	    (args, "zss", &tracker_server, &group_name, &storage_id)) {
		printf("usage: " FDFSPYMOD
		       ".fdfs_delete_server(tracker_server | None, group_name, storage_id)\n");
		fdfs_client_destroy();
		return NULL;
	}

	if (tracker_server == NULL) {
		if (g_tracker_group.server_count > 1) {
			srand(time(NULL));
			rand();	//discard the first
			g_tracker_group.server_index =
			    (int) ((g_tracker_group.server_count *
				    (double) rand())
				   / (double)
				   RAND_MAX);
		}
	} else {
		int i;
		char ip_addr[IP_ADDRESS_SIZE];

		*ip_addr = '\0';
		if (getIpaddrByName
		    (tracker_server, ip_addr, sizeof(ip_addr))
		    == INADDR_NONE) {
			printf("resolve ip address of tracker server: %s "
			       "fail!\n", tracker_server);
			return Py_BuildValue("i", 2);
		}

		for (i = 0; i < g_tracker_group.server_count; i++) {
			if (strcmp(g_tracker_group.servers[i].ip_addr,
				   ip_addr) == 0) {
				g_tracker_group.server_index = i;
				break;
			}
		}

		if (i == g_tracker_group.server_count) {
			printf("tracker server: %s not exists!\n",
			       tracker_server);
			return Py_BuildValue("i", 2);
		}
	}

	pTrackerServer = tracker_get_connection();
	if (pTrackerServer == NULL) {
		fdfs_client_destroy();
		result = errno != 0 ? errno : ECONNREFUSED;
		return Py_BuildValue("i", result);
	}

	if ((result =
	     tracker_delete_storage(&g_tracker_group,
				    group_name, storage_id)) != 0) {
		printf
		    ("delete storage server %s::%s fail, "
		     "error no: %d, error info: %s\n",
		     group_name, storage_id, result, STRERROR(result));
	}

	tracker_disconnect_server_ex(pTrackerServer, true);
	return Py_BuildValue("i", result);
}

static PyObject *fdfs_set_trunk_server(PyObject * self, PyObject * args)
{
	ConnectionInfo *pTrackerServer;
	int result;
	char *tracker_server;
	char *group_name;
	char *storage_id;
	char new_trunk_server_id[FDFS_STORAGE_ID_MAX_SIZE];

	if (!PyArg_ParseTuple
	    (args, "zss", &tracker_server, &group_name, &storage_id)) {
		printf("usage: " FDFSPYMOD
		       ".fdfs_set_trunk_server(tracker_server | None, group_name, storage_id)\n");
		fdfs_client_destroy();
		return NULL;
	}

	if (tracker_server == NULL) {
		if (g_tracker_group.server_count > 1) {
			srand(time(NULL));
			rand();	//discard the first
			g_tracker_group.server_index =
			    (int) ((g_tracker_group.server_count *
				    (double) rand())
				   / (double)
				   RAND_MAX);
		}
	} else {
		int i;
		char ip_addr[IP_ADDRESS_SIZE];

		*ip_addr = '\0';
		if (getIpaddrByName
		    (tracker_server, ip_addr, sizeof(ip_addr))
		    == INADDR_NONE) {
			printf("resolve ip address of tracker server: %s "
			       "fail!\n", tracker_server);
			return Py_BuildValue("i", 2);
		}

		for (i = 0; i < g_tracker_group.server_count; i++) {
			if (strcmp(g_tracker_group.servers[i].ip_addr,
				   ip_addr) == 0) {
				g_tracker_group.server_index = i;
				break;
			}
		}

		if (i == g_tracker_group.server_count) {
			printf("tracker server: %s not exists!\n",
			       tracker_server);
			return Py_BuildValue("i", 2);
		}
	}

	pTrackerServer = tracker_get_connection();
	if (pTrackerServer == NULL) {
		fdfs_client_destroy();
		result = errno != 0 ? errno : ECONNREFUSED;
		return Py_BuildValue("i", result);
	}

	if ((result = tracker_set_trunk_server(&g_tracker_group,
					       group_name,
					       storage_id,
					       new_trunk_server_id))
	    != 0) {
		printf("set trunk server %s::%s fail, "
		       "error no: %d, error info: %s\n",
		       group_name, storage_id, result, STRERROR(result));
	}

	tracker_disconnect_server_ex(pTrackerServer, true);
	return Py_BuildValue("(i, s)", result, new_trunk_server_id);
}

static PyObject *fdfs_destroy(PyObject * self)
{
	fdfs_client_destroy();
	return Py_BuildValue("s", "client exited");
}

// 方法列表
static PyMethodDef FDFSMethods[] = {

	//python中注册的函数名
	{"fdfs_init", fdfs_init, METH_VARARGS,
	 "fdfsclient init."},
	{"fdfs_upload", fdfs_upload, METH_VARARGS,
	 "fdfsclient upload."},
	{"fdfs_download", fdfs_download, METH_VARARGS,
	 "fdfsclient download."},
	{"fdfs_delete", fdfs_delete, METH_VARARGS,
	 "fdfsclient delete."},
	{"fdfs_getmeta", fdfs_getmeta, METH_VARARGS,
	 "fdfsclient getmeta."},
	{"fdfs_setmeta", fdfs_setmeta, METH_VARARGS,
	 "fdfsclient setmeta."},
	{"fdfs_query_servers", fdfs_query_servers, METH_VARARGS,
	 "fdfsclient query servers."},
	{"fdfs_upload_append", fdfs_upload_append, METH_VARARGS,
	 "fdfsclient upload append."},
	{"fdfs_append_file", fdfs_append_file, METH_VARARGS,
	 "fdfsclient append file."},
	{"fdfs_file_info", fdfs_file_info, METH_VARARGS,
	 "fdfsclient file info."},
	{"fdfs_list_all_groups", fdfs_list_all_groups, METH_VARARGS,
	 "fdfsclient list all groups or one group."},
	//{"fdfs_list_storages",  fdfs_list_storages, METH_VARARGS,
	// "fdfsclient list storages."},
	{"fdfs_delete_group", fdfs_delete_group, METH_VARARGS,
	 "fdfsclient delete one group."},
	{"fdfs_delete_server", fdfs_delete_server, METH_VARARGS,
	 "fdfsclient delete one storages server."},
	{"fdfs_set_trunk_server", fdfs_set_trunk_server, METH_VARARGS,
	 "fdfsclient set trunk server."},
	{"fdfs_destroy", (PyCFunction) fdfs_destroy, METH_NOARGS,
	 "fdfsclient destroy."},
	{NULL, NULL, 0, NULL}
};

// 模块初始化方法
PyMODINIT_FUNC initfdfspyclient()
{

	//初始模块
	PyObject *m = Py_InitModule("fdfspyclient", FDFSMethods);
	if (m == NULL)
		return;
}

static int writeToFileCallback(void *arg, const int64_t file_size,
			       const char *data, const int current_size)
{
	if (arg == NULL) {
		return EINVAL;
	}

	if (fwrite(data, current_size, 1, (FILE *) arg) != 1) {
		return errno != 0 ? errno : EIO;
	}

	return 0;
}

static int uploadFileCallback(void *arg, const int64_t file_size, int sock)
{
	int64_t total_send_bytes;
	char *filename;

	if (arg == NULL) {
		return EINVAL;
	}

	filename = (char *) arg;
	return tcpsendfile(sock, filename, file_size,
			   g_fdfs_network_timeout, &total_send_bytes);
}

static int list_storages(ConnectionInfo * pTrackerServer,
			 FDFSGroupStat * pGroupStat)
{
	int result;
	int storage_count;
	FDFSStorageInfo storage_infos[FDFS_MAX_SERVERS_EACH_GROUP];
	FDFSStorageInfo *p;
	FDFSStorageInfo *pStorage;
	FDFSStorageInfo *pStorageEnd;
	FDFSStorageStat *pStorageStat;
	char szJoinTime[32];
	char szUpTime[32];
	char szLastHeartBeatTime[32];
	char szSrcUpdTime[32];
	char szSyncUpdTime[32];
	char szSyncedTimestamp[32];
	char szSyncedDelaySeconds[128];
	char szHostname[128];
	char szHostnamePrompt[128 + 8];
	int k;
	int max_last_source_update;

	printf("group name = %s\n"
	       "disk total space = %" PRId64 " MB\n"
	       "disk free space = %" PRId64 " MB\n"
	       "trunk free space = %" PRId64 " MB\n"
	       "storage server count = %d\n"
	       "active server count = %d\n"
	       "storage server port = %d\n"
	       "storage HTTP port = %d\n"
	       "store path count = %d\n"
	       "subdir count per path = %d\n"
	       "current write server index = %d\n"
	       "current trunk file id = %d\n\n",
	       pGroupStat->group_name,
	       pGroupStat->total_mb,
	       pGroupStat->free_mb,
	       pGroupStat->trunk_free_mb,
	       pGroupStat->count,
	       pGroupStat->active_count,
	       pGroupStat->storage_port,
	       pGroupStat->storage_http_port,
	       pGroupStat->store_path_count,
	       pGroupStat->subdir_count_per_path,
	       pGroupStat->current_write_server,
	       pGroupStat->current_trunk_file_id);

	result = tracker_list_servers(pTrackerServer,
				      pGroupStat->group_name, NULL,
				      storage_infos,
				      FDFS_MAX_SERVERS_EACH_GROUP,
				      &storage_count);
	if (result != 0) {
		return result;
	}

	k = 0;
	pStorageEnd = storage_infos + storage_count;
	for (pStorage = storage_infos; pStorage < pStorageEnd; pStorage++) {
		max_last_source_update = 0;
		for (p = storage_infos; p < pStorageEnd; p++) {
			if (p != pStorage && p->stat.last_source_update
			    > max_last_source_update) {
				max_last_source_update =
				    p->stat.last_source_update;
			}
		}

		pStorageStat = &(pStorage->stat);
		if (max_last_source_update == 0) {
			*szSyncedDelaySeconds = '\0';
		} else {
			if (pStorageStat->last_synced_timestamp == 0) {
				strcpy(szSyncedDelaySeconds,
				       "(never synced)");
			} else {
				int delay_seconds;
				int remain_seconds;
				int day;
				int hour;
				int minute;
				int second;
				char szDelayTime[64];

				delay_seconds =
				    (int) (max_last_source_update -
					   pStorageStat->last_synced_timestamp);
				day = delay_seconds / (24 * 3600);
				remain_seconds =
				    delay_seconds % (24 * 3600);
				hour = remain_seconds / 3600;
				remain_seconds %= 3600;
				minute = remain_seconds / 60;
				second = remain_seconds % 60;

				if (day != 0) {
					sprintf(szDelayTime, "%d days "
						"%02dh:%02dm:%02ds",
						day, hour, minute, second);
				} else if (hour != 0) {
					sprintf(szDelayTime,
						"%02dh:%02dm:%02ds", hour,
						minute, second);
				} else if (minute != 0) {
					sprintf(szDelayTime, "%02dm:%02ds",
						minute, second);
				} else {
					sprintf(szDelayTime, "%ds",
						second);
				}

				sprintf(szSyncedDelaySeconds, "(%s delay)",
					szDelayTime);
			}
		}

		getHostnameByIp(pStorage->ip_addr, szHostname,
				sizeof(szHostname));
		if (*szHostname != '\0') {
			sprintf(szHostnamePrompt, " (%s)", szHostname);
		} else {
			*szHostnamePrompt = '\0';
		}

		if (pStorage->up_time != 0) {
			formatDatetime(pStorage->up_time,
				       "%Y-%m-%d %H:%M:%S",
				       szUpTime, sizeof(szUpTime));
		} else {
			*szUpTime = '\0';
		}

		printf("\tStorage %d:\n"
		       "\t\tid = %s\n"
		       "\t\tip_addr = %s%s  %s\n"
		       "\t\thttp domain = %s\n"
		       "\t\tversion = %s\n"
		       "\t\tjoin time = %s\n"
		       "\t\tup time = %s\n"
		       "\t\ttotal storage = %d MB\n"
		       "\t\tfree storage = %d MB\n"
		       "\t\tupload priority = %d\n"
		       "\t\tstore_path_count = %d\n"
		       "\t\tsubdir_count_per_path = %d\n"
		       "\t\tstorage_port = %d\n"
		       "\t\tstorage_http_port = %d\n"
		       "\t\tcurrent_write_path = %d\n"
		       "\t\tsource storage id = %s\n"
		       "\t\tif_trunk_server = %d\n"
		       "\t\tconnection.alloc_count = %d\n"
		       "\t\tconnection.current_count = %d\n"
		       "\t\tconnection.max_count = %d\n"
		       "\t\ttotal_upload_count = %" PRId64 "\n"
		       "\t\tsuccess_upload_count = %" PRId64 "\n"
		       "\t\ttotal_append_count = %" PRId64 "\n"
		       "\t\tsuccess_append_count = %" PRId64 "\n"
		       "\t\ttotal_modify_count = %" PRId64 "\n"
		       "\t\tsuccess_modify_count = %" PRId64 "\n"
		       "\t\ttotal_truncate_count = %" PRId64 "\n"
		       "\t\tsuccess_truncate_count = %" PRId64 "\n"
		       "\t\ttotal_set_meta_count = %" PRId64 "\n"
		       "\t\tsuccess_set_meta_count = %" PRId64 "\n"
		       "\t\ttotal_delete_count = %" PRId64 "\n"
		       "\t\tsuccess_delete_count = %" PRId64 "\n"
		       "\t\ttotal_download_count = %" PRId64 "\n"
		       "\t\tsuccess_download_count = %" PRId64 "\n"
		       "\t\ttotal_get_meta_count = %" PRId64 "\n"
		       "\t\tsuccess_get_meta_count = %" PRId64 "\n"
		       "\t\ttotal_create_link_count = %" PRId64 "\n"
		       "\t\tsuccess_create_link_count = %" PRId64 "\n"
		       "\t\ttotal_delete_link_count = %" PRId64 "\n"
		       "\t\tsuccess_delete_link_count = %" PRId64 "\n"
		       "\t\ttotal_upload_bytes = %" PRId64 "\n"
		       "\t\tsuccess_upload_bytes = %" PRId64 "\n"
		       "\t\ttotal_append_bytes = %" PRId64 "\n"
		       "\t\tsuccess_append_bytes = %" PRId64 "\n"
		       "\t\ttotal_modify_bytes = %" PRId64 "\n"
		       "\t\tsuccess_modify_bytes = %" PRId64 "\n"
		       "\t\tstotal_download_bytes = %" PRId64 "\n"
		       "\t\tsuccess_download_bytes = %" PRId64 "\n"
		       "\t\ttotal_sync_in_bytes = %" PRId64 "\n"
		       "\t\tsuccess_sync_in_bytes = %" PRId64 "\n"
		       "\t\ttotal_sync_out_bytes = %" PRId64 "\n"
		       "\t\tsuccess_sync_out_bytes = %" PRId64 "\n"
		       "\t\ttotal_file_open_count = %" PRId64 "\n"
		       "\t\tsuccess_file_open_count = %" PRId64 "\n"
		       "\t\ttotal_file_read_count = %" PRId64 "\n"
		       "\t\tsuccess_file_read_count = %" PRId64 "\n"
		       "\t\ttotal_file_write_count = %" PRId64 "\n"
		       "\t\tsuccess_file_write_count = %" PRId64 "\n"
		       "\t\tlast_heart_beat_time = %s\n"
		       "\t\tlast_source_update = %s\n"
		       "\t\tlast_sync_update = %s\n"
		       "\t\tlast_synced_timestamp = %s %s\n",
		       ++k, pStorage->id, pStorage->ip_addr,
		       szHostnamePrompt,
		       get_storage_status_caption(pStorage->status),
		       pStorage->domain_name, pStorage->version,
		       formatDatetime(pStorage->join_time,
				      "%Y-%m-%d %H:%M:%S", szJoinTime,
				      sizeof(szJoinTime)), szUpTime,
		       pStorage->total_mb, pStorage->free_mb,
		       pStorage->upload_priority,
		       pStorage->store_path_count,
		       pStorage->subdir_count_per_path,
		       pStorage->storage_port, pStorage->storage_http_port,
		       pStorage->current_write_path, pStorage->src_id,
		       pStorage->if_trunk_server,
		       pStorageStat->connection.alloc_count,
		       pStorageStat->connection.current_count,
		       pStorageStat->connection.max_count,
		       pStorageStat->total_upload_count,
		       pStorageStat->success_upload_count,
		       pStorageStat->total_append_count,
		       pStorageStat->success_append_count,
		       pStorageStat->total_modify_count,
		       pStorageStat->success_modify_count,
		       pStorageStat->total_truncate_count,
		       pStorageStat->success_truncate_count,
		       pStorageStat->total_set_meta_count,
		       pStorageStat->success_set_meta_count,
		       pStorageStat->total_delete_count,
		       pStorageStat->success_delete_count,
		       pStorageStat->total_download_count,
		       pStorageStat->success_download_count,
		       pStorageStat->total_get_meta_count,
		       pStorageStat->success_get_meta_count,
		       pStorageStat->total_create_link_count,
		       pStorageStat->success_create_link_count,
		       pStorageStat->total_delete_link_count,
		       pStorageStat->success_delete_link_count,
		       pStorageStat->total_upload_bytes,
		       pStorageStat->success_upload_bytes,
		       pStorageStat->total_append_bytes,
		       pStorageStat->success_append_bytes,
		       pStorageStat->total_modify_bytes,
		       pStorageStat->success_modify_bytes,
		       pStorageStat->total_download_bytes,
		       pStorageStat->success_download_bytes,
		       pStorageStat->total_sync_in_bytes,
		       pStorageStat->success_sync_in_bytes,
		       pStorageStat->total_sync_out_bytes,
		       pStorageStat->success_sync_out_bytes,
		       pStorageStat->total_file_open_count,
		       pStorageStat->success_file_open_count,
		       pStorageStat->total_file_read_count,
		       pStorageStat->success_file_read_count,
		       pStorageStat->total_file_write_count,
		       pStorageStat->success_file_write_count,
		       formatDatetime(pStorageStat->last_heart_beat_time,
				      "%Y-%m-%d %H:%M:%S",
				      szLastHeartBeatTime,
				      sizeof(szLastHeartBeatTime)),
		       formatDatetime(pStorageStat->last_source_update,
				      "%Y-%m-%d %H:%M:%S", szSrcUpdTime,
				      sizeof(szSrcUpdTime)),
		       formatDatetime(pStorageStat->last_sync_update,
				      "%Y-%m-%d %H:%M:%S", szSyncUpdTime,
				      sizeof(szSyncUpdTime)),
		       formatDatetime(pStorageStat->last_synced_timestamp,
				      "%Y-%m-%d %H:%M:%S",
				      szSyncedTimestamp,
				      sizeof(szSyncedTimestamp)),
		       szSyncedDelaySeconds);
	}

	return 0;
}

static int list_all_groups(ConnectionInfo * pTrackerServer,
			   const char *group_name)
{
	int result;
	int group_count;
	FDFSGroupStat group_stats[FDFS_MAX_GROUPS];
	FDFSGroupStat *pGroupStat;
	FDFSGroupStat *pGroupEnd;
	int i;

	result = tracker_list_groups(pTrackerServer,
				     group_stats, FDFS_MAX_GROUPS,
				     &group_count);
	if (result != 0) {
		tracker_close_all_connections();
		fdfs_client_destroy();
		return result;
	}

	pGroupEnd = group_stats + group_count;
	if (group_name == NULL) {
		printf("group count: %d\n", group_count);
		i = 0;
		for (pGroupStat = group_stats; pGroupStat < pGroupEnd;
		     pGroupStat++) {
			printf("\nGroup %d:\n", ++i);
			list_storages(pTrackerServer, pGroupStat);
		}
	} else {
		for (pGroupStat = group_stats; pGroupStat < pGroupEnd;
		     pGroupStat++) {
			if (strcmp(pGroupStat->group_name, group_name) ==
			    0) {
				list_storages(pTrackerServer, pGroupStat);
				break;
			}
		}
	}

	return 0;
}


text:
describe('Services', function(){

  describe('Chat service', function(){

    var $httpBackend, chat;

    beforeEach(module('tcApp'));

    beforeEach(inject(function($injector){
      $httpBackend = $injector.get('$httpBackend');
      chat = $injector.get('Chat');

    }));

    it('sends a POST request when user submit new message', function(){
      $httpBackend.expectPOST('/api/v1/chat').respond(200);
      var msgData = {
        author:'Unit Test',
        text:'unit test',
        date:new Date()
      };
      chat.sendMessage(msgData);
      $httpBackend.flush();
    });

  });

});


text:
using System;
using System.Text.Json;
using Azure.Core;

namespace Azure.ResourceManager.Compute.Models
{
    public partial class BootDiagnosticsInstanceView
    {
        internal static BootDiagnosticsInstanceView DeserializeBootDiagnosticsInstanceView(JsonElement element)
        {
            Optional<Uri> consoleScreenshotBlobUri = default;
            Optional<Uri> serialConsoleLogBlobUri = default;
            Optional<InstanceViewStatus> status = default;
            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("consoleScreenshotBlobUri"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        consoleScreenshotBlobUri = null;
                        continue;
                    }
                    consoleScreenshotBlobUri = new Uri(property.Value.GetString());
                    continue;
                }
                if (property.NameEquals("serialConsoleLogBlobUri"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        serialConsoleLogBlobUri = null;
                        continue;
                    }
                    serialConsoleLogBlobUri = new Uri(property.Value.GetString());
                    continue;
                }
                if (property.NameEquals("status"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    status = InstanceViewStatus.DeserializeInstanceViewStatus(property.Value);
                    continue;
                }
            }
            return new BootDiagnosticsInstanceView(consoleScreenshotBlobUri.Value, serialConsoleLogBlobUri.Value, status.Value);
        }
    }
}


text:
title: How Weave works
layout: default
---

## How does it work?

A weave network consists of a number of 'peers' - weave routers
residing on different hosts. Each peer has a name, which tends to
remain the same over restarts, and a unique identifier (UID) which is
different each time it is run.  These are opaque identifiers as far as
the router is concerned, although the name defaults to a MAC address.

Weave routers establish TCP connections to each other, over which they
perform a protocol handshake and subsequently exchange
[topology](#topology) information. These connections are encrypted if
so configured. Peers also establish UDP "connections", possibly
encrypted, which carry encapsulated network packets. These
"connections" are duplex and can traverse firewalls.

Weave creates a network bridge on the host. Each container is
connected to that bridge via a veth pair, the container side of which
is given the IP address & netmask supplied in 'weave run'. Also
connected to the bridge is the weave router container.

A weave router captures Ethernet packets from its bridge-connected
interface in promiscuous mode, using 'pcap'. This typically excludes
traffic between local containers, and between the host and local
containers, all of which is routed straight over the bridge by the
kernel. Captured packets are forwarded over UDP to weave router peers
running on other hosts. On receipt of such a packet, a router injects
the packet on its bridge interface using 'pcap' and/or forwards the
packet to peers.

Weave routers learn which peer host a particular MAC address resides
on. They combine this knowledge with topology information in order to
make routing decisions and thus avoid forwarding every packet to every
peer. Weave can route packets in partially connected networks with
changing topology. For example, in this network, peer 1 is connected
directly to 2 and 3, but if 1 needs to send a packet to 4 or 5 it must
first send it to peer 3:
![Partially connected Weave Network](images/top-diag1.png "Partially connected Weave Network")

### Encapsulation

When the weave router forwards packets, the encapsulation looks
something like this:

    +-----------------------------------+
    | Name of sending peer              |
    +-----------------------------------+
    | Frame 1: Name of capturing peer   |
    +-----------------------------------+
    | Frame 1: Name of destination peer |
    +-----------------------------------+
    | Frame 1: Captured payload length  |
    +-----------------------------------+
    | Frame 1: Captured payload         |
    +-----------------------------------+
    | Frame 2: Name of capturing peer   |
    +-----------------------------------+
    | Frame 2: Name of destination peer |
    +-----------------------------------+
    | Frame 2: Captured payload length  |
    +-----------------------------------+
    | Frame 2: Captured payload         |
    +-----------------------------------+
    |                ...                |
    +-----------------------------------+
    | Frame N: Name of capturing peer   |
    +-----------------------------------+
    | Frame N: Name of destination peer |
    +-----------------------------------+
    | Frame N: Captured payload length  |
    +-----------------------------------+
    | Frame N: Captured payload         |
    +-----------------------------------+

The name of the sending peer enables the receiving peer to identify
who sent this UDP packet. This is followed by the meta data and
payload for one or more captured frames. The router performs batching:
if it captures several frames very quickly that all need forwarding to
the same peer, it fits as many of them as possible into a single
UDP packet.

The meta data for each frame contains the names of the capturing and
destination peers. Since the name of the capturing peer name is
associated with the source MAC of the captured payload, it allows
receiving peers to build up their mappings of which client MAC
addresses are local to which peers. The destination peer name enables
the receiving peer to identify whether this frame is destined for
itself or whether it should be forwarded on to some other peer,
accommodating multi-hop routing. This works even when the receiving
intermediate peer has no knowledge of the destination MAC: only the
original capturing peer needs to determine the destination peer from
the MAC. This way weave peers never need to exchange the MAC addresses
of clients and need not take any special action for ARP traffic and
MAC discovery.

### Topology

The topology information captures which peers are connected to which
other peers. Weave peers communicate their knowledge of the topology
(and changes to it) to their neighbours, who then pass this
information on to their own neighbours, and so on, until the entire
network knows about any change.

Topology is communicated over the TCP links between peers, using a
Gossip mechanism.  Topology messages are sent by a peer...

- when a connection has been added; the entire topology is sent to the
  remote peer, and an incremental update, containing information on
  just the two peers at the ends of the connection, is sent to all
  neighbours,
- when a connection has been marked as 'established', indicating that
  the remote peer can receive UDP traffic from the peer; an update
  containing just information about the local peer is sent to all
  neighbours,
- when a connection has been torn down; an update containing just
  information about the local peer is sent to all neighbours,
- periodically, on a timer, in case someone has missed an update.

The receiver of a topology update merges that update with its own
topology model, adding peers hitherto unknown to it, and updating
peers for which the update contains a more recent version than known
to it. If there were any such new/updated peers, then an improved
update containing them is sent out on all connections.

If the update mentions a peer that the receiver does not know, then
the entire update is ignored.

#### Message details
Every gossip message is structured as follows:

    +-----------------------------------+
    | 1-byte message type - Gossip      |
    +-----------------------------------+
    | 4-byte Gossip channel - Topology  |
    +-----------------------------------+
    | Peer Name of source               |
    +-----------------------------------+
    | Gossip payload (topology update)  |
    +-----------------------------------+

The topology update payload is laid out like this:

    +-----------------------------------+
    | Peer 1: Name                      |
    +-----------------------------------+
    | Peer 1: UID                       |
    +-----------------------------------+
    | Peer 1: Version number            |
    +-----------------------------------+
    | Peer 1: List of connections       |
    +-----------------------------------+
    |                ...                |
    +-----------------------------------+
    | Peer N: Name                      |
    +-----------------------------------+
    | Peer N: UID                       |
    +-----------------------------------+
    | Peer N: Version number            |
    +-----------------------------------+
    | Peer N: List of connections       |
    +-----------------------------------+

Each List of connections is encapsulated as a byte buffer, within
which the structure is:

    +-----------------------------------+
    | Connection 1: Remote Peer Name    |
    +-----------------------------------+
    | Connection 1: Remote IP address   |
    +-----------------------------------+
    | Connection 2: Remote Peer Name    |
    +-----------------------------------+
    | Connection 2: Remote IP address   |
    +-----------------------------------+
    |                ...                |
    +-----------------------------------+
    | Connection N: Remote Peer Name    |
    +-----------------------------------+
    | Connection N: Remote IP address   |
    +-----------------------------------+

#### Removal of peers
If a peer, after receiving a topology update, sees that another peer
no longer has any connections within the network, it drops all
knowledge of that second peer.

#### Out-of-date topology
The peer-to-peer gossiping of updates is not instantaneous, so it is
very possible for a node elsewhere in the network to have an
out-of-date view.

If the destination peer for a packet is still reachable, then
out-of-date topology can result in it taking a less efficient route.

If the out-of-date topology makes it look as if the destination peer
is not reachable, then the packet is dropped.  For most protocols
(e.g. TCP), the transmission will be retried a short time later, by
which time the topology should have updated.

### Crypto

Weave can be configured to encrypt both the data passing over the TCP
connections and the payloads of UDP packets sent between peers. This
is accomplished using the [NaCl](http://nacl.cr.yp.to/) crypto
libraries, employing Curve25519, XSalsa20 and Poly1305 to encrypt and
authenticate messages. Weave protects against injection and replay
attacks for traffic forwarded between peers.

NaCl was selected because of its good reputation both in terms of
selection and implementation of ciphers, but equally importantly, its
clear APIs, good documentation and high-quality
[go implementation](https://godoc.org/golang.org/x/crypto/nacl). It is
quite difficult to use NaCl incorrectly. Contrast this with libraries
such as OpenSSL where the library and its APIs are vast in size,
poorly documented, and easily used wrongly.

#### Establishing the Ephemeral Session Key

For every connection between peers, a fresh public/private key pair is
created at both ends, using NaCl's `GenerateKey` function. The public
key portion is sent to the other end as part of the initial handshake
performed over TCP. Peers that were started with a password do not
continue with connection establishment unless they receive a public
key from the remote peer. Thus either all peers in a weave network
must be supplied with a password, or none.

When a peer has received a public key from the remote peer, it uses
this to form the ephemeral session key for this connection. The public
key from the remote peer is combined with the private key for the
local peer in the usual Diffie-Hellman way, resulting in both peers
arriving at the same shared key. To this is appended the supplied
password, and the result is hashed through SHA256, to form the final
ephemeral session key. Thus the supplied password is never exchanged
directly, and is thoroughly mixed into the shared secret. The shared
key formed by Diffie-Hellman is 256 bits long, appending the password
to this obviously makes it longer by an unknown amount, and the use of
SHA256 reduces this back to 256 bits, to form the final ephemeral
session key. This late combination with the password eliminates "Man
In The Middle" attacks: sniffing the public key exchange between the
two peers and faking their responses will not grant an attacker
knowledge of the password, and so an attacker would not be able to
form valid ephemeral session keys.

The same ephemeral session key is used for both TCP and UDP traffic
between two peers.

#### TCP

TCP connection are only used to exchange topology information between
peers, via a message-based protocol. The router generates a fresh
192-bit random nonce for every message to be sent, and prepends the
nonce to the encrypted message, as is normal in NaCl, so that the
receiver knows the nonce. Encryption of each message is carried out
using NaCl's `secretbox.Seal` function using the ephemeral session
key. Each TCP connection has a monotonically incrementing message
counter, the current value of which is included in the encrypted part
of the message. Given the assumption that TCP is reliable and ordered,
a message received via TCP is only acted upon if the message counter
in the received message is the expected message counter. This prevents
replay attacks on the TCP connection.

As TCP connections do not carry captured traffic, minimising message
size or latency is not a major concern, so the potentially substantial
increase in length of messages by prepending the full nonce, or the
cost of generating a fresh random nonce for each message is not
considered likely to cause problems. The random nonces are created by
the go `crypto/rand` package, which implements a cryptographically
secure pseudorandom number generator.

#### UDP

UDP connections carry captured traffic between peers. For a UDP packet
sent between peers that are using crypto, the encapsulation looks as
follows:

    +-----------------------------------+
    | Name of sending peer              |
    +-----------------------------------+
    | Nonce offset and flags            |
    +-----------------------------------+
    | NaCl SecretBox overheads          |
    +-----------------------------------+ -+
    | Frame 1: Name of capturing peer   |  |
    +-----------------------------------+  | This section is encrypted
    | Frame 1: Name of destination peer |  | using the ephemeral session
    +-----------------------------------+  | key between the weave peers
    | Frame 1: Captured payload length  |  | sending and receiving this
    +-----------------------------------+  | packet.
    | Frame 1: Captured payload         |  |
    +-----------------------------------+  |
    | Frame 2: Name of capturing peer   |  |
    +-----------------------------------+  |
    | Frame 2: Name of destination peer |  |
    +-----------------------------------+  |
    | Frame 2: Captured payload length  |  |
    +-----------------------------------+  |
    | Frame 2: Captured payload         |  |
    +-----------------------------------+  |
    |                ...                |  |
    +-----------------------------------+  |
    | Frame N: Name of capturing peer   |  |
    +-----------------------------------+  |
    | Frame N: Name of destination peer |  |
    +-----------------------------------+  |
    | Frame N: Captured payload length  |  |
    +-----------------------------------+  |
    | Frame N: Captured payload         |  |
    +-----------------------------------+ -+

This is very similar to the [non-crypto encapsulation](#encapsulation).

All of the frames are encrypted with the same ephemeral session key
and all must be decrypted by the receiving peer. Frames which are to
be forwarded on to some further peer will be re-encrypted with the
relevant ephemeral session keys for the onward connections. Thus all
traffic is fully decrypted on every peer it passes through.
Encryption is again done with the NaCl `secretbox.Seal` function.

The name of the sending peer enables the receiver to identify the peer
who sent this UDP packet, and in turn to determine which ephemeral
session key was used and which nonce, and perform decryption. To avoid
sending a fresh 192-bit nonce with every UDP packet, which would pose
an unacceptable overhead, each UDP packet only carries the lowest 15
bits of the nonce, which is treated as an offset from the "established
nonce". The lifecycle of a nonce for UDP is:

1. A fresh nonce is generated and the most significant 177 bits are
sent to the receiving peer over the TCP connection. These upper most
177 bits are used for the next 2^15 (32768) UDP messages. This is the
"established nonce".

2. Each UDP message carries the lowest 15 bits as a unique counter. Thus
the lowest 15 bits are combined with (appended to) the uppermost 177
bits to form the unique nonce for that message.

3. Once the sending side has sent the 16384'th message on the current
nonce (50% of the way through the available range), it generates a new
nonce (upper 177 bits only) and sends that over the TCP connection,
thus hopefully ensuring it arrives and is ready before it is
needed. The sending side will switch to using the new nonce once the
full 32768 messages of the current nonce have been used. At this
point, the sending side resets the offset to 0.

4. The receiving side must deal with the fact that UDP is unreliable
and unordered. The receiving side keeps track of the highest offset
seen for each established nonce. The condition to switching to the new
nonce it has received via the TCP connection is: the highest offset
seen for the current nonce must be above 24576 (75% of the available
range) _and_ the current message just received must have an offset
less than 8192 (25% of the available range) _and_ the new offset must
be less than 8192 messages *ahead* of the highest seen offset so far
(assuming modulo 32768). If these conditions are met, the highest
offset is set to the offset of the current message and the new nonce
is used. If those conditions are not met, the receiving side continues
with the current nonce (according to the rules below), updating the
highest offset seen as appropriate. Thus in order for the nonce to not
be updated correctly would require a loss of at least 8192 messages.

5. When the receiving side switches to the new nonce, it does not
discard the old nonce. If the highest offset seen is below 8192 (25% of
the range) _and_ the current message offset is above 24576 (75% of the
range), _and_ the current message offset is less than 8192 behind the
highest seen nonce (assuming modulo 32768), then the current message is
decoded with the old nonce.

6. In the remaining cases, the current message is only decoded if its
offset is within 8192 either side of the highest seen offset.

7. To avoid replay attacks, the receiving side keeps a set of which
offsets have been used with the current and previous nonce. If the
offset doesn't exist in the set, and the message can be correctly
decoded, the offset is added to the relevant set (thus we avoid
poisoning attacks). If the offset already exists in the set, or the
message cannot be correctly decoded, the message is not processed
further.

### Further reading
More details on the inner workings of weave can be found in the
[architecture documentation](https://github.com/zettio/weave/blob/master/docs/architecture.txt).


text:
// Copyright 2013 Jerry Hongy.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package lua

/*
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include "clua.h"
*/
import "C"
import (
	//"io"
	"fmt"
	//"unsafe"
	"reflect"
	//"strings"
	//"errors"
	"runtime"
)

type ILuaRef interface {
	ILuaRef()
	PushValue(state State)
	Release()
}

type RefLua struct {
	VM  *VM
	Ref int
}

type Table struct {
	RefLua
}

type Function struct {
	RefLua
}

func (self *RefLua) init(state State, lobject int) {
	self.VM = state.VM
	C.lua_pushvalue(state.L, C.int(lobject))
	refvalue := C.luaL_ref(state.L, C.LUA_REGISTRYINDEX)
	self.Ref = int(refvalue)
	runtime.SetFinalizer(self, func(r *RefLua) {
		r.Release()
	})
}

func (state State) NewLuaRef(lobject int) *RefLua {
	r := new(RefLua)
	r.init(state, lobject)
	return r
}

func (state State) NewLuaTable(lobject int) *Table {
	t := new(Table)
	t.init(state, lobject)
	return t
}

func (state State) NewLuaFunction(lobject int) *Function {
	f := new(Function)
	f.init(state, lobject)
	return f
}

func (self *RefLua) PushValue(state State) {
	if self.Ref != 0 && self.VM.globalL != nil {
		C.lua_rawgeti(state.L, C.LUA_REGISTRYINDEX, C.int(self.Ref))
	}
}

//
// release reference to lua object
//
func (self *RefLua) Release() {
	if self.Ref != 0 && self.VM.globalL != nil {
		C.luaL_unref(self.VM.globalL, C.LUA_REGISTRYINDEX, C.int(self.Ref))
	}
	self.VM = nil
	self.Ref = 0
}

func callLuaFunc(state State, in []interface{}, nout int) ([]interface{}, error) {
	inv := make([]reflect.Value, 0, len(in))
	for _, x := range in {
		inv = append(inv, reflect.ValueOf(x))
	}
	return callLuaFuncUtil(state, inv, nout)
}

//
// call a lua function
//
func (fn *Function) Call(in ...interface{}) ([]interface{}, error) {
	if fn.Ref == 0 {
		return make([]interface{}, 0), fmt.Errorf("cannot call a released lua function")
	}
	L := fn.VM.globalL
	state := State{fn.VM, L}
	fn.PushValue(state)
	return callLuaFunc(state, in, -1)
}

func (fn *Function) VCallWith(in []reflect.Value, nout int) ([]interface{}, error) {
	if fn.Ref == 0 {
		return make([]interface{}, 0), fmt.Errorf("cannot call a released lua function")
	}
	L := fn.VM.globalL
	state := State{fn.VM, L}
	fn.PushValue(state)
	return callLuaFuncUtil(state, in, nout)
}

func (fn *Function) CallWith(in []interface{}, nout int) ([]interface{}, error) {
	if fn.Ref == 0 {
		return make([]interface{}, 0), fmt.Errorf("cannot call a released lua function")
	}
	L := fn.VM.globalL
	state := State{fn.VM, L}
	fn.PushValue(state)
	return callLuaFunc(state, in, nout)
}

func (fn *Function) String() string {
	return fmt.Sprintf("<lua fuction @%v>", fn.Ref)
}

func (tbl *Table) Set(key interface{}, value interface{}) (bool, error) {
	if tbl.Ref == 0 {
		return false, fmt.Errorf("cannot set a released lua table")
	}
	L := tbl.VM.globalL
	state := State{tbl.VM, L}
	bottom := C.lua_gettop(L)
	defer C.lua_settop(L, bottom)

	tbl.PushValue(state)

	vkey := reflect.ValueOf(key)
	ok := state.goToLuaValue(vkey)
	if !ok {
		return false, fmt.Errorf("invalid key type for lua type: %v", vkey.Kind())
	}
	state.goToLuaValue(reflect.ValueOf(value))
	C.lua_settable(L, C.int(-3))

	return true, nil
}

func (tbl *Table) GetWithError(key interface{}) (interface{}, error) {
	if tbl.Ref == 0 {
		return nil, fmt.Errorf("cannot get a released lua table")
	}
	L := tbl.VM.globalL
	state := State{tbl.VM, L}
	bottom := C.lua_gettop(L)
	defer C.lua_settop(L, bottom)

	tbl.PushValue(state)

	vkey := reflect.ValueOf(key)
	ok := state.goToLuaValue(vkey)
	if !ok {
		return nil, fmt.Errorf("invalid key type for lua type: %v", vkey.Kind())
	}
	C.lua_gettable(L, C.int(-2))
	vvalue, err := state.luaToGoValue(-1, nil)
	if err != nil {
		return nil, err
	}

	if vvalue.IsValid() {
		return vvalue.Interface(), nil
	}
	return nil, nil
}

func (tbl *Table) Get(key interface{}) interface{} {
	v, _ := tbl.GetWithError(key)
	return v
}

func (tbl *Table) GetnWithError() (int, error) {
	if tbl.Ref == 0 {
		return 0, fmt.Errorf("cannot get lenght a released lua table")
	}
	L := tbl.VM.globalL
	state := State{tbl.VM, L}
	bottom := int(C.lua_gettop(L))
	defer C.lua_settop(L, C.int(bottom))

	tbl.PushValue(state)

	n := int(C.lua_objlen(L, C.int(-1)))
	return n, nil
}

func (tbl *Table) Getn() int {
	n, _ := tbl.GetnWithError()
	return n
}

func (tbl *Table) Foreach(fn func(key interface{}, value interface{}) bool) {
	if tbl.Ref == 0 {
		return
	}

	L := tbl.VM.globalL
	state := State{tbl.VM, L}
	bottom := C.lua_gettop(L)
	defer C.lua_settop(L, bottom)
	tbl.PushValue(state)

	ltable := C.lua_gettop(L)
	C.lua_pushnil(L)
	for {
		if 0 == C.lua_next(L, ltable) {
			return
		}

		vkey, err := state.luaToGoValue(-2, nil)
		if err != nil {
			return
		}
		vvalue, err := state.luaToGoValue(-1, nil)
		if err != nil {
			return
		}

		cont := fn(vkey.Interface(), vvalue.Interface())
		if !cont {
			return
		}

		C.lua_settop(L, -2)
	}
}

func (tbl *Table) String() string {
	return fmt.Sprintf("<lua table @%v>", tbl.Ref)
}


text:
package it.inaf.android;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class AppsFragment extends ListFragment {

    ArrayList<AppItem> mItemList;
    AppListAdapter mAdapter;
    Callbacks mCallbacks;

    public interface Callbacks
    {
        void onItemSelected(Bundle args);
    }

    static class ViewHolder
    {
        ImageView image;
        TextView name;
    }

    private class AppListAdapter extends ArrayAdapter<AppItem>
    {
        private Context mContext;
        private ArrayList<AppItem> objects = null;

        public AppListAdapter(Context context, int textviewid, ArrayList<AppItem> objects)
        {
            super(context, textviewid, objects);
            mContext = context;
            this.objects = objects;
        }

        @Override
        public int getCount()
        {
            return ((null != objects) ? objects.size() : 0);
        }

        @Override
        public long getItemId(int position)
        {
            return position;
        }

        @Override
        public AppItem getItem(int position)
        {
            return ((null != objects) ? objects.get(position) : null);
        }

        public View getView(int position, View convertView, ViewGroup parent)
        {
            ViewHolder holder;
            if(convertView == null)
            {
                LayoutInflater li = LayoutInflater.from(mContext);
                convertView = li.inflate(R.layout.app_item, parent, false);

                holder = new ViewHolder();
                holder.image = (ImageView)convertView.findViewById(R.id.apps_list_image);
                holder.name = (TextView)convertView.findViewById(R.id.apps_list_name);

                convertView.setTag(holder);
            }
            else
            {
                holder = (ViewHolder) convertView.getTag();
            }

            AppItem data = objects.get(position);

            if(data == null)
                return convertView;

            holder.name.setText(data.name);

            holder.image.setTag(data.iconurl);
            holder.image.setImageResource(R.drawable.empty);
            INAF.imageLoader.get(data.iconurl, new ImageListener(holder.image));

            return convertView;
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // Activities containing this fragment must implement its callbacks.
        if (!(activity instanceof Callbacks)) {
            throw new IllegalStateException("Activity must implement fragment's callbacks.");
        }

        mCallbacks = (Callbacks) activity;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(savedInstanceState != null)
        {
            mItemList = (ArrayList<AppItem>) savedInstanceState.getSerializable("item_list");
        }
        else {
            mItemList = new ArrayList<AppItem>();

            JSONArray json = INAF.loadJson(getActivity(), "json_apps");

            int length = json.length();

            for (int i = 0; i < length; i++) {
                try {
                    AppItem appItem = new AppItem();
                    JSONObject obj = json.getJSONObject(i);
                    appItem.id = obj.getString("id");
                    appItem.name = obj.getString("name");
                    appItem.descr = obj.getString("descr");
                    appItem.authors = obj.getString("authors");
                    appItem.iconurl = obj.getString("iconurl");
                    appItem.infourl = obj.getString("infourl");
                    appItem.iosurl = obj.getString("iosurl");
                    appItem.androidurl = obj.getString("androidurl");
                    appItem.price = obj.getString("price");
                    appItem.lang = obj.getString("lang");
                    appItem.notes = obj.getString("notes");

                    mItemList.add(appItem);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }

        mAdapter = new AppListAdapter(getActivity(), R.layout.feed_item, mItemList);
        setListAdapter(mAdapter);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id)
    {
        super.onListItemClick(l, v, position, id);

        AppItem item = mItemList.get(position);
        Bundle bundle = new Bundle();
        bundle.putSerializable("link", item.infourl);
        mCallbacks.onItemSelected(bundle);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putSerializable("item_list", mItemList);
    }
}


text:
var express = require('express')
var router = require('express').Router()

router.use(express.static(__dirname + '/../frontend/dist'))

router.get('/', function (req, res) {
  res.sendfile('./frontend/dist/index.html')
})

router.get('/api/messages', function (req, res, next) {
  Post.find()
    .sort('-date')
    .exec((err, messages) => {
      if (err) {
        return next(err)
      }
      res.json(messages)
    })
})
//}

module.exports = router;