Skip to content

Commit

Permalink
🎨 上传记录功能
Browse files Browse the repository at this point in the history
  • Loading branch information
adlered committed Sep 3, 2024
1 parent 1ef509c commit b76a1ba
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,26 @@
import org.b3log.latke.ioc.BeanManager;
import org.b3log.latke.ioc.Inject;
import org.b3log.latke.ioc.Singleton;
import org.b3log.latke.model.User;
import org.b3log.latke.repository.*;
import org.b3log.latke.service.LangPropsService;
import org.b3log.latke.util.Requests;
import org.b3log.latke.util.Strings;
import org.b3log.latke.util.URLs;
import org.b3log.symphony.Server;
import org.b3log.symphony.model.Common;
import org.b3log.symphony.processor.middleware.LoginCheckMidware;
import org.b3log.symphony.repository.UploadRepository;
import org.b3log.symphony.util.*;
import org.b3log.symphony.util.Sessions;
import org.json.JSONObject;

import java.io.*;
import java.net.InetAddress;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -85,15 +92,20 @@ public class FileUploadProcessor {
@Inject
private LangPropsService langPropsService;

@Inject
private UploadRepository uploadRepository;

/**
* Register request handlers.
*/
public static void register() {
final BeanManager beanManager = BeanManager.getInstance();

final FileUploadProcessor fileUploadProcessor = beanManager.getReference(FileUploadProcessor.class);
final LoginCheckMidware loginCheck = beanManager.getReference(LoginCheckMidware.class);

Dispatcher.get("/upload/{yyyy}/{MM}/{file}", fileUploadProcessor::getFile);
Dispatcher.post("/upload", fileUploadProcessor::uploadFile);
Dispatcher.post("/upload", fileUploadProcessor::uploadFile, loginCheck::handle);
// Dispatcher.post("/fetch-upload", fileUploadProcessor::fetchUpload);
}

Expand Down Expand Up @@ -269,6 +281,24 @@ public synchronized void uploadFile(final RequestContext context) {

final CountDownLatch countDownLatch = new CountDownLatch(files.size());
for (int i = 0; i < files.size(); i++) {
// 检查该文件是否已经上传过
String md5 = MD5Calculator.calculateMd5(fileBytes.get(i));
final Query query = new Query().setFilter(new PropertyFilter("md5", FilterOperator.EQUAL, md5));
try {
final List<JSONObject> md5s = uploadRepository.getList(query);
if (!md5s.isEmpty()) {
JSONObject md5in1 = md5s.get(0);
String url = md5in1.optString("path");
String[] filename = url.split("/");
String originalName = url.split("/")[filename.length - 1];
succMap.put(originalName, url);
countDownLatch.countDown();
LOGGER.log(Level.INFO, "Same MD5 " + originalName + " gives: " + url);
continue;
}
} catch (RepositoryException ignored) {
}
// 没有重复文件,正常上传
final FileUpload file = files.get(i);
final String originalName = fileName = Escapes.sanitizeFilename(file.getFilename());
try {
Expand All @@ -290,7 +320,7 @@ public synchronized void uploadFile(final RequestContext context) {
bytes = fileBytes.get(i);
final String contentType = file.getContentType();
com.qiniu.http.Response response = uploadManager.put(bytes, fileName, uploadToken, null, contentType, false);
//解析上传成功的结果
// 解析上传成功的结果
JSONObject putRet = new JSONObject(response.bodyString());
countDownLatch.countDown();
url = Symphonys.UPLOAD_QINIU_DOMAIN + "/" + putRet.optString("key");
Expand All @@ -306,6 +336,19 @@ public synchronized void uploadFile(final RequestContext context) {
url = Latkes.getServePath() + "/upload/" + fileName;
succMap.put(originalName, url);
}
// 记录到Upload表
JSONObject user = Sessions.getUser();
try {
user = ApiProcessor.getUserByKey(context.param("apiKey"));
} catch (NullPointerException ignored) {
}
final String userName = user.optString(User.USER_NAME);
String ip = Requests.getRemoteAddr(request);
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
// 写入数据库
final Transaction transaction = uploadRepository.beginTransaction();
uploadRepository.add(suffix, userName, ip, time, url, md5, true);
transaction.commit();
} catch (final Exception e) {
LOGGER.log(Level.ERROR, "Uploads file failed", e);

Expand Down
47 changes: 47 additions & 0 deletions src/main/java/org/b3log/symphony/repository/UploadRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Rhythm - A modern community (forum/BBS/SNS/blog) platform written in Java.
* Modified version from Symphony, Thanks Symphony :)
* Copyright (C) 2012-present, b3log.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.b3log.symphony.repository;

import org.b3log.latke.repository.AbstractRepository;
import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.repository.annotation.Repository;
import org.json.JSONObject;

@Repository
public class UploadRepository extends AbstractRepository {
/**
* Public constructor.
*/
public UploadRepository() {
super("upload");
}

public void add(String type, String userName, String ip, String time, String path, String md5, boolean isPublic) throws RepositoryException {
JSONObject jsonObject = new JSONObject();
jsonObject.put("type", type);
jsonObject.put("userName", userName);
jsonObject.put("ip", ip);
jsonObject.put("time", time);
jsonObject.put("path", path);
jsonObject.put("md5", md5);
jsonObject.put("public", isPublic);
add(jsonObject);
}

}
59 changes: 59 additions & 0 deletions src/main/java/org/b3log/symphony/util/MD5Calculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.b3log.symphony.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;

public class MD5Calculator {

public static String bytesToHex(byte[] hash) {
StringBuilder hexString = new StringBuilder(2 * hash.length);
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if(hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}

public static String calculateMd5(List<byte[]> fileBytes) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");

// 遍历每个byte[]并更新digest
for (byte[] bytes : fileBytes) {
digest.update(bytes);
}

// 完成哈希计算
byte[] hash = digest.digest();

// 将字节数组转换为十六进制字符串
return bytesToHex(hash);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 algorithm not found", e);
}
}

public static String calculateMd5(byte[] input) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] hash = digest.digest(input); // 计算MD5散列

// 将字节数组转换为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 algorithm not found", e);
}
}
}

0 comments on commit b76a1ba

Please sign in to comment.