<commit_before>package com.qcloud.video.api;

import java.io.File;
import java.net.URLEncoder;
import java.util.HashMap;

import org.json.JSONObject;

import com.qcloud.video.common.HMACSHA1;
import com.qcloud.video.common.Request;
import com.qcloud.video.common.Sign;

public class VideoCloud {
	/**
	 * @brief Cos类
	 * @author robinslsun
	 */
	final String VIDEO_CGI_URL = "http://web.video.myqcloud.com/files/v1/";
	public enum FolderPattern {File, Folder, Both};
	private int appId;
	private String secretId;
	private String secretKey;
	private int timeOut;
	
	/**
	 * VideoCloud 构造方法
	 * @param appId			授权appid
	 * @param secretId		授权secret id
	 * @param secretKey	 授权secret key
	 */
	public VideoCloud(int appId, String secretId, String secretKey){
		this(appId, secretId, secretKey, 60);
	}
	
	/**
	 * VideoCloud 构造方法
	 * @param appId			授权appid
	 * @param secretId		授权secret id
	 * @param secretKey	 授权secret key
	 * @param timeOut	网络超时
	 */
	public VideoCloud(int appId, String secretId, String secretKey, int timeOut){
		this.appId = appId;
		this.secretId = secretId;
		this.secretKey = secretKey;
		this.timeOut = timeOut * 1000;
	}
	
	/**
	 * 远程路径Encode处理
	 * @param remotePath
	 * @return
	 */
	private String encodeRemotePath(String remotePath)
    {
		if(remotePath.equals("/")){
			return remotePath;
		}
		boolean endWith = remotePath.endsWith("/");
        String[] part = remotePath.split("/");
        remotePath = "";
        for(String s : part){
        	if (!s.equals(""))
            {
        		if(remotePath != ""){
        			remotePath += "/";
        		}
                remotePath += URLEncoder.encode(s);
            }
        }
        remotePath = (remotePath.startsWith("/") ? "" : "/") + remotePath + (endWith ? "/" : "");
        return remotePath;
    }

	/**
	 * 标准化远程路径
	 * @param remotePath 要标准化的远程路径
	 * @return
	 */
    private String standardizationRemotePath(String remotePath)
    {
        if (!remotePath.startsWith("/"))
        {
            remotePath = "/" + remotePath;
        }
        if (!remotePath.endsWith("/"))
        {
            remotePath += "/";
        }
        return remotePath;
    }
	
	/**
	 * 更新文件夹信息
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件夹路径
	 * @param bizAttribute 更新信息
	 * @return
	 * @throws Exception 
	 */
	public String updateFolder(String bucketName, String remotePath, String bizAttribute) throws Exception{
		
		remotePath = standardizationRemotePath(remotePath);
		String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath);
		HashMap<String, Object> data = new HashMap<String, Object>();
		data.put("op", "update");
		data.put("biz_attr", bizAttribute);
		String sign = Sign.appSignOnce(appId, secretId, secretKey, (remotePath.startsWith("/") ? "" : "/") + remotePath, bucketName);
		String qcloud_sign = sign.toString();
		HashMap<String, String> header = new HashMap<String, String>();
		header.put("Authorization", qcloud_sign);
		header.put("Content-Type","application/json");
		return Request.sendRequest(url, data, "POST", header, timeOut);
	}
	
	/**
	 * 更新文件信息
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件路径
	 * @param bizAttribute 更新信息
	 * @return
	 * @throws Exception 
	 */
	public String updateFile(String bucketName, String remotePath, String bizAttribute, String title, String desc) throws Exception{
		String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath);
		HashMap<String, Object> data = new HashMap<String, Object>();
		data.put("op", "update");
		data.put("biz_attr", bizAttribute);
		data.put("title", title);
		data.put("desc", desc);
		String sign = Sign.appSignOnce(appId, secretId, secretKey, (remotePath.startsWith("/") ? "" : "/") + remotePath, bucketName);
		String qcloud_sign = sign.toString();
		HashMap<String, String> header = new HashMap<String, String>();
		header.put("Authorization", qcloud_sign);
		header.put("Content-Type","application/json");
		return Request.sendRequest(url, data, "POST", header, timeOut);
	}
	
	/**
	 * 删除文件夹
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件夹路径
	 * @return
	 * @throws Exception 
	 */
	public String deleteFolder(String bucketName, String remotePath) throws Exception{
		remotePath = standardizationRemotePath(remotePath);
		return deleteFile(bucketName, remotePath);
	}
	
	/**
	 * 删除文件
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件路径及文件名，格式/path/filename
	 * @return
	 * @throws Exception 
	 */
	public String deleteFile(String bucketName, String remotePath) throws Exception{
		String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath);
		HashMap<String, Object> data = new HashMap<String, Object>();
		data.put("op", "delete");
		String sign = Sign.appSignOnce(appId, secretId, secretKey, (remotePath.startsWith("/") ? "" : "/") + remotePath, bucketName);
		HashMap<String, String> header = new HashMap<String, String>();
		header.put("Authorization", sign);
		header.put("Content-Type","application/json");
		return Request.sendRequest(url, data, "POST", header, timeOut);
	}
	
	/**
	 * 获取文件夹信息
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件夹路径
	 * @return
	 * @throws Exception 
	 */
	public String getFolderStat(String bucketName, String remotePath) throws Exception{
		remotePath = standardizationRemotePath(remotePath);
		return getFileStat(bucketName, remotePath);
	}
	
	/**
	 * 获取文件信息
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件路径
	 * @return
	 * @throws Exception 
	 */
	public String getFileStat(String bucketName, String remotePath) throws Exception{
		String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath);
		HashMap<String, Object> data = new HashMap<String, Object>();
		data.put("op", "stat");
		long expired = System.currentTimeMillis() / 1000 + 60;
		String sign = Sign.appSign(appId, secretId, secretKey, expired, bucketName);
		HashMap<String, String> header = new HashMap<String, String>();
		header.put("Authorization", sign);
		return Request.sendRequest(url, data, "GET", header, timeOut);
	}
	
	/**
	 * 创建文件夹
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件夹路径
	 * @return
	 * @throws Exception 
	 */
	public String createFolder(String bucketName, String remotePath, String bizAttribute) throws Exception{
		remotePath = standardizationRemotePath(remotePath);
		String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath);
		HashMap<String, Object> data = new HashMap<String, Object>();
		data.put("op", "create");
		data.put("biz_attr", "bizAttribute");
		long expired = System.currentTimeMillis() / 1000 + 60;
		String sign = Sign.appSign(appId, secretId, secretKey, expired, bucketName);
		HashMap<String, String> header = new HashMap<String, String>();
		header.put("Authorization", sign);
		header.put("Content-Type","application/json");
		return Request.sendRequest(url, data, "POST", header, timeOut);
	}
	
	/**
	 * 目录列表
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件夹路径
	 * @param num 拉取的总数
	 * @param offset 透传字段,用于翻页,前端不需理解,需要往前/往后翻页则透传回来 
	 * @param order 默认正序(=0), 填1为反序
	 * @param pattern 拉取模式:只是文件，只是文件夹，全部
	 * @return
	 * @throws Exception 
	 */
	public String getFolderList(String bucketName, String remotePath, int num, String offset, int order, FolderPattern pattern) throws Exception{
		remotePath = standardizationRemotePath(remotePath);
		return getFolderList(bucketName, remotePath, "", num, offset, order, pattern);
	}
	
	/**
	 * 目录列表,前缀搜索
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件夹路径
	 * @param prefix 读取文件/文件夹前缀
	 * @param num 拉取的总数
	 * @param offset 透传字段,用于翻页,前端不需理解,需要往前/往后翻页则透传回来 
	 * @param order 默认正序(=0), 填1为反序
	 * @param pattern 拉取模式:只是文件，只是文件夹，全部
	 * @return
	 * @throws Exception 
	 */
	public String getFolderList(String bucketName, String remotePath, String prefix, int num, String offset, int order, FolderPattern pattern) throws Exception{
		remotePath = standardizationRemotePath(remotePath);
		String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath) + URLEncoder.encode(prefix);
		HashMap<String, Object> data = new HashMap<String, Object>();
		data.put("op", "list");
		data.put("num", num);
		data.put("offset", offset);
		data.put("order", order);
		String[] patternArray = {"eListFileOnly", "eListDirOnly", "eListBoth"};
		data.put("pattern", patternArray[pattern.ordinal()]);
		long expired = System.currentTimeMillis() / 1000 + 60;
		String sign = Sign.appSign(appId, secretId, secretKey, expired, bucketName);
		HashMap<String, String> header = new HashMap<String, String>();
		header.put("Authorization", sign);
		return Request.sendRequest(url, data, "GET", header, timeOut);
	}
	
	/**
	 * 单个文件上传
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件路径
	 * @param localPath 本地文件路径
	 * @return
	 * @throws Exception 
	 */
	public String uploadFile(String bucketName, String remotePath, String localPath) throws Exception{
		
		try {			
			String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath);
			String sha1 = HMACSHA1.getFileSha1(localPath);
			HashMap<String, Object> data = new HashMap<String, Object>();
			data.put("op", "upload");<commit_msg>context<commit_after>package com.qcloud.video.api;

import java.io.File;
import java.net.URLEncoder;
import java.util.HashMap;

import org.json.JSONObject;

import com.qcloud.video.common.HMACSHA1;
import com.qcloud.video.common.Request;
import com.qcloud.video.common.Sign;

public class VideoCloud {
	/**
	 * @brief Cos类
	 * @author robinslsun
	 */
	final String VIDEO_CGI_URL = "http://web.video.myqcloud.com/files/v1/";
	public enum FolderPattern {File, Folder, Both};
	private int appId;
	private String secretId;
	private String secretKey;
	private int timeOut;
	
	/**
	 * VideoCloud 构造方法
	 * @param appId			授权appid
	 * @param secretId		授权secret id
	 * @param secretKey	 授权secret key
	 */
	public VideoCloud(int appId, String secretId, String secretKey){
		this(appId, secretId, secretKey, 60);
	}
	
	/**
	 * VideoCloud 构造方法
	 * @param appId			授权appid
	 * @param secretId		授权secret id
	 * @param secretKey	 授权secret key
	 * @param timeOut	网络超时
	 */
	public VideoCloud(int appId, String secretId, String secretKey, int timeOut){
		this.appId = appId;
		this.secretId = secretId;
		this.secretKey = secretKey;
		this.timeOut = timeOut * 1000;
	}
	
	/**
	 * 远程路径Encode处理
	 * @param remotePath
	 * @return
	 */
	private String encodeRemotePath(String remotePath)
    {
		if(remotePath.equals("/")){
			return remotePath;
		}
		boolean endWith = remotePath.endsWith("/");
        String[] part = remotePath.split("/");
        remotePath = "";
        for(String s : part){
        	if (!s.equals(""))
            {
        		if(remotePath != ""){
        			remotePath += "/";
        		}
                remotePath += URLEncoder.encode(s);
            }
        }
        remotePath = (remotePath.startsWith("/") ? "" : "/") + remotePath + (endWith ? "/" : "");
        return remotePath;
    }

	/**
	 * 标准化远程路径
	 * @param remotePath 要标准化的远程路径
	 * @return
	 */
    private String standardizationRemotePath(String remotePath)
    {
        if (!remotePath.startsWith("/"))
        {
            remotePath = "/" + remotePath;
        }
        if (!remotePath.endsWith("/"))
        {
            remotePath += "/";
        }
        return remotePath;
    }
	
	/**
	 * 更新文件夹信息
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件夹路径
	 * @param bizAttribute 更新信息
	 * @return
	 * @throws Exception 
	 */
	public String updateFolder(String bucketName, String remotePath, String bizAttribute) throws Exception{
		
		remotePath = standardizationRemotePath(remotePath);
		String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath);
		HashMap<String, Object> data = new HashMap<String, Object>();
		data.put("op", "update");
		data.put("biz_attr", bizAttribute);
		String sign = Sign.appSignOnce(appId, secretId, secretKey, (remotePath.startsWith("/") ? "" : "/") + remotePath, bucketName);
		String qcloud_sign = sign.toString();
		HashMap<String, String> header = new HashMap<String, String>();
		header.put("Authorization", qcloud_sign);
		header.put("Content-Type","application/json");
		return Request.sendRequest(url, data, "POST", header, timeOut);
	}
	
	/**
	 * 更新文件信息
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件路径
	 * @param bizAttribute 更新信息
	 * @return
	 * @throws Exception 
	 */
	public String updateFile(String bucketName, String remotePath, String bizAttribute, String title, String desc) throws Exception{
		String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath);
		HashMap<String, Object> data = new HashMap<String, Object>();
		data.put("op", "update");
		data.put("biz_attr", bizAttribute);
		data.put("title", title);
		data.put("desc", desc);
		String sign = Sign.appSignOnce(appId, secretId, secretKey, (remotePath.startsWith("/") ? "" : "/") + remotePath, bucketName);
		String qcloud_sign = sign.toString();
		HashMap<String, String> header = new HashMap<String, String>();
		header.put("Authorization", qcloud_sign);
		header.put("Content-Type","application/json");
		return Request.sendRequest(url, data, "POST", header, timeOut);
	}
	
	/**
	 * 删除文件夹
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件夹路径
	 * @return
	 * @throws Exception 
	 */
	public String deleteFolder(String bucketName, String remotePath) throws Exception{
		remotePath = standardizationRemotePath(remotePath);
		return deleteFile(bucketName, remotePath);
	}
	
	/**
	 * 删除文件
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件路径及文件名，格式/path/filename
	 * @return
	 * @throws Exception 
	 */
	public String deleteFile(String bucketName, String remotePath) throws Exception{
		String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath);
		HashMap<String, Object> data = new HashMap<String, Object>();
		data.put("op", "delete");
		String sign = Sign.appSignOnce(appId, secretId, secretKey, (remotePath.startsWith("/") ? "" : "/") + remotePath, bucketName);
		HashMap<String, String> header = new HashMap<String, String>();
		header.put("Authorization", sign);
		header.put("Content-Type","application/json");
		return Request.sendRequest(url, data, "POST", header, timeOut);
	}
	
	/**
	 * 获取文件夹信息
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件夹路径
	 * @return
	 * @throws Exception 
	 */
	public String getFolderStat(String bucketName, String remotePath) throws Exception{
		remotePath = standardizationRemotePath(remotePath);
		return getFileStat(bucketName, remotePath);
	}
	
	/**
	 * 获取文件信息
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件路径
	 * @return
	 * @throws Exception 
	 */
	public String getFileStat(String bucketName, String remotePath) throws Exception{
		String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath);
		HashMap<String, Object> data = new HashMap<String, Object>();
		data.put("op", "stat");
		long expired = System.currentTimeMillis() / 1000 + 60;
		String sign = Sign.appSign(appId, secretId, secretKey, expired, bucketName);
		HashMap<String, String> header = new HashMap<String, String>();
		header.put("Authorization", sign);
		return Request.sendRequest(url, data, "GET", header, timeOut);
	}
	
	/**
	 * 创建文件夹
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件夹路径
	 * @return
	 * @throws Exception 
	 */
	public String createFolder(String bucketName, String remotePath, String bizAttribute) throws Exception{
		remotePath = standardizationRemotePath(remotePath);
		String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath);
		HashMap<String, Object> data = new HashMap<String, Object>();
		data.put("op", "create");
		data.put("biz_attr", "bizAttribute");
		long expired = System.currentTimeMillis() / 1000 + 60;
		String sign = Sign.appSign(appId, secretId, secretKey, expired, bucketName);
		HashMap<String, String> header = new HashMap<String, String>();
		header.put("Authorization", sign);
		header.put("Content-Type","application/json");
		return Request.sendRequest(url, data, "POST", header, timeOut);
	}
	
	/**
	 * 目录列表
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件夹路径
	 * @param num 拉取的总数
	 * @param context 透传字段，查看第一页，则传空字符串。若需要翻页，需要将前一页返回值中的context透传到参数中。order用于指定翻页顺序。若order填0，则从当前页正序/往下翻页；若order填1，则从当前页倒序/往上翻页。
	 * @param order 默认正序(=0), 填1为反序
	 * @param pattern 拉取模式:只是文件，只是文件夹，全部
	 * @return
	 * @throws Exception 
	 */
	public String getFolderList(String bucketName, String remotePath, int num, String context, int order, FolderPattern pattern) throws Exception{
		remotePath = standardizationRemotePath(remotePath);
		return getFolderList(bucketName, remotePath, "", num, context, order, pattern);
	}
	
	/**
	 * 目录列表,前缀搜索
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件夹路径
	 * @param prefix 读取文件/文件夹前缀
	 * @param num 拉取的总数
	 * @param context 透传字段，查看第一页，则传空字符串。若需要翻页，需要将前一页返回值中的context透传到参数中。order用于指定翻页顺序。若order填0，则从当前页正序/往下翻页；若order填1，则从当前页倒序/往上翻页。
	 * @param order 默认正序(=0), 填1为反序
	 * @param pattern 拉取模式:只是文件，只是文件夹，全部
	 * @return
	 * @throws Exception 
	 */
	public String getFolderList(String bucketName, String remotePath, String prefix, int num, String context, int order, FolderPattern pattern) throws Exception{
		remotePath = standardizationRemotePath(remotePath);
		String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath) + URLEncoder.encode(prefix);
		HashMap<String, Object> data = new HashMap<String, Object>();
		data.put("op", "list");
		data.put("num", num);
		data.put("context", context);
		data.put("order", order);
		String[] patternArray = {"eListFileOnly", "eListDirOnly", "eListBoth"};
		data.put("pattern", patternArray[pattern.ordinal()]);
		long expired = System.currentTimeMillis() / 1000 + 60;
		String sign = Sign.appSign(appId, secretId, secretKey, expired, bucketName);
		HashMap<String, String> header = new HashMap<String, String>();
		header.put("Authorization", sign);
		return Request.sendRequest(url, data, "GET", header, timeOut);
	}
	
	/**
	 * 单个文件上传
	 * @param bucketName bucket名称
	 * @param remotePath 远程文件路径
	 * @param localPath 本地文件路径
	 * @return
	 * @throws Exception 
	 */
	public String uploadFile(String bucketName, String remotePath, String localPath) throws Exception{
		
		try {			
			String url = VIDEO_CGI_URL + appId + "/" + bucketName + encodeRemotePath(remotePath);
			String sha1 = HMACSHA1.getFileSha1(localPath);
			HashMap<String, Object> data = new HashMap<String, Object>();
			data.put("op", "upload");
{'fraction_non_alphanumeric': 0.13290218270008083, 'fraction_numerical': 0.00377256804095931, 'mean_word_length': 4.079660552970162, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7477579', 'n_tokens_mistral': 6655, 'n_tokens_neox': 6412, 'n_words': 1413}