├── .gitignore
├── LICENSE
├── README.md
├── UPDATE.md
├── release
├── FileUp4Github.jar
├── app.config
└── preview
│ ├── drag.png
│ └── upload.png
└── src
├── nicelee
└── github
│ ├── config
│ └── Config.java
│ ├── runnable
│ └── ThUpload.java
│ ├── ui
│ └── MainFrame.java
│ └── upload
│ └── FileUploader.java
├── resources
└── github_logo.png
└── test
└── junit
└── FileUploaderTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | /.project
2 | /.settings
3 | /.classpath
4 | */download
5 | *.zip
6 | /bin
7 | /target
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FileUploader4Github
2 | 
3 | 
4 | 
5 | 
6 | 
7 | 
8 |
9 | 基于GitHub API的GitHub文件上传工具
10 | ===============================
11 | **仅需Java环境即可运行**
12 |
13 | ## :smile:如何配置
14 | + 配置释义
15 | 因为是上传到Github仓库,故而需要`owner`、`repo`,在仓库中的位置`path`,以及授权用的`token`。
16 | 这些都应该实现保存在jar包同目录下的`app.config`文件中。举例如下:
17 | ```
18 | owner = nICEnnnnnnnLee
19 | repo = AbcTest
20 | path = /note/hello/
21 | token = 06495cbd3c86f38dd4b1e5a75249b14804d08tt5
22 | ```
23 |
24 | + 注意事项
25 | + `path`应该以`/`开头,并且以`/`结尾,如根目录,`path = /`
26 | + `path`应当不包含中文等特殊字符
27 | + `path`在上传前可以不存在,上传文件时自动建立
28 | + `token`请在[这里](https://github.com/settings/tokens)设置并获取,`repo`相关权限打勾即可
29 | + 仅支持上传新文件,若路径存在同名文件,将上传失败
30 |
31 |
32 | ## :smile:如何使用
33 | + 独立运行
34 | + `Release`页下载、解压,并配置好`app.config`
35 | + 双击`FileUp4Github.jar`
36 | + 确认上传至云端时是否保存为原来的文件名/根据时间重命名
37 | + 选择想要上传的文件
38 | + 通过窗口选择(单个文件)
39 | + 通过拖拽选择(单个或多个文件均可)
40 | 
41 | + 控制台查看结果(上传完毕后,文件链接将复制到系统剪贴板)
42 | 
43 |
44 | + 嵌入第三方程序
45 | 以下为示例,
46 | ```
47 | // 构造url链接 https://api.github.com/repos/:owner/:repo/contents/:path
48 | String url = "https://api.github.com/repos/nICEnnnnnnnLee/AbcTest/contents/note/test.jpg";
49 |
50 | // 获取想要上传的文件
51 | File file = new File("D:\\Workspace\\sources\\pics\\test.jpg");
52 |
53 | // 上传,并获取结果
54 | boolean result = FileUploader.create(url, file, ":token");
55 | ```
56 |
57 | ## :smile:其它
58 | * **下载地址**: [https://github.com/nICEnnnnnnnLee/FileUploader4Github/releases](https://github.com/nICEnnnnnnnLee/FileUploader4Github/releases)
59 | * [**更新日志**](https://github.com/nICEnnnnnnnLee/FileUploader4Github/blob/master/UPDATE.md)
60 |
61 |
62 | LICENSE
63 |
64 |
65 | ```
66 | Copyright (C) 2019 NiceLee. All Rights Reserved.
67 |
68 | Licensed under the Apache License, Version 2.0 (the "License");
69 | you may not use this file except in compliance with the License.
70 | You may obtain a copy of the License at
71 |
72 | http://www.apache.org/licenses/LICENSE-2.0
73 |
74 | Unless required by applicable law or agreed to in writing, software
75 | distributed under the License is distributed on an "AS IS" BASIS,
76 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
77 | See the License for the specific language governing permissions and
78 | limitations under the License.
79 | ```
80 |
81 |
--------------------------------------------------------------------------------
/UPDATE.md:
--------------------------------------------------------------------------------
1 | ## UPDATE
2 | * v0.1
3 | * 初始版本
--------------------------------------------------------------------------------
/release/FileUp4Github.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nICEnnnnnnnLee/FileUploader4Github/3a3eefa90fa1eeec7a587a3b884f3ca76d0fd5de/release/FileUp4Github.jar
--------------------------------------------------------------------------------
/release/app.config:
--------------------------------------------------------------------------------
1 | owner = nICEnnnnnnnLee
2 | repo = AbcTest
3 | path = /task/
4 | token = 1bf077833092bf5d0fa46572ea1beb0878ab1e21
--------------------------------------------------------------------------------
/release/preview/drag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nICEnnnnnnnLee/FileUploader4Github/3a3eefa90fa1eeec7a587a3b884f3ca76d0fd5de/release/preview/drag.png
--------------------------------------------------------------------------------
/release/preview/upload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nICEnnnnnnnLee/FileUploader4Github/3a3eefa90fa1eeec7a587a3b884f3ca76d0fd5de/release/preview/upload.png
--------------------------------------------------------------------------------
/src/nicelee/github/config/Config.java:
--------------------------------------------------------------------------------
1 | package nicelee.github.config;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.FileReader;
5 | import java.io.IOException;
6 | import java.util.regex.Matcher;
7 | import java.util.regex.Pattern;
8 |
9 | public class Config {
10 |
11 | public static String owner;
12 | public static String repo;
13 | public static String path; // 想要上传的文件路径,请确保"/"开头,"/"结尾
14 | public static String token;
15 |
16 | final static Pattern patternConfig = Pattern.compile("^[ ]*([0-9|a-z|A-Z|.|_]+)[ ]*=[ ]*([^ ]+.*$)");
17 | public static void readFromFile() {
18 | // 从配置文件读取
19 | BufferedReader buReader = null;
20 | System.out.println("----Config init begin...----");
21 | try {
22 | buReader = new BufferedReader(new FileReader("./app.config"));
23 | String config;
24 | while ((config = buReader.readLine()) != null) {
25 | Matcher matcher = patternConfig.matcher(config);
26 | if (matcher.find()) {
27 | switch (matcher.group(1)) {
28 | case "owner":
29 | owner = matcher.group(2).trim();
30 | break;
31 | case "repo":
32 | repo = matcher.group(2).trim();
33 | break;
34 | case "path":
35 | path = matcher.group(2).trim();
36 | break;
37 | case "token":
38 | token = matcher.group(2).trim();
39 | break;
40 | default:
41 | break;
42 | }
43 | System.out.printf(" key-->value: %s --> %s\r\n", matcher.group(1), matcher.group(2));
44 | }
45 | }
46 | } catch (IOException e) {
47 | // e.printStackTrace();
48 | } finally {
49 | try {
50 | buReader.close();
51 | } catch (Exception e) {
52 | }
53 | }
54 | System.out.println("----Config ini end...----");
55 | // 下载设置相关
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/nicelee/github/runnable/ThUpload.java:
--------------------------------------------------------------------------------
1 | package nicelee.github.runnable;
2 |
3 | import java.awt.Toolkit;
4 | import java.awt.datatransfer.Clipboard;
5 | import java.awt.datatransfer.StringSelection;
6 | import java.awt.datatransfer.Transferable;
7 | import java.io.File;
8 | import java.net.URLEncoder;
9 | import java.text.SimpleDateFormat;
10 | import java.util.Date;
11 | import java.util.concurrent.ExecutorService;
12 | import java.util.concurrent.Executors;
13 |
14 | import javax.swing.JTextArea;
15 | import javax.swing.JTextField;
16 |
17 | import nicelee.github.config.Config;
18 | import nicelee.github.upload.FileUploader;
19 |
20 | public class ThUpload implements Runnable {
21 |
22 | public static ExecutorService uploadThreadPool = Executors.newFixedThreadPool(1);
23 | public static Integer count = 0;
24 | static String token;
25 | static JTextArea consoleArea;
26 | static JTextField fPath;
27 |
28 | boolean isRename;
29 | File file;
30 |
31 | /**
32 | * 初始化参数
33 | *
34 | * @param token
35 | * @param label
36 | * @param fPath
37 | */
38 | public static void init(String token, JTextArea consoleArea, JTextField fPath) {
39 | ThUpload.token = token;
40 | ThUpload.consoleArea = consoleArea;
41 | ThUpload.fPath = fPath;
42 | }
43 |
44 | /**
45 | * 将任务加入队列
46 | *
47 | * @param fName
48 | * @param file
49 | */
50 | public static void addUploadTask(File file, boolean isRename) {
51 | synchronized (count) {
52 | count++;
53 | }
54 | uploadThreadPool.execute(new ThUpload(file, isRename));
55 | }
56 |
57 | private ThUpload(File file, boolean isRename) {
58 | this.isRename = isRename;
59 | this.file = file;
60 | }
61 |
62 | @Override
63 | public void run() {
64 | synchronized (fPath) {
65 | fPath.setText(file.getAbsolutePath());
66 | consoleArea.append("当前任务数: " + count + "\n");
67 | consoleArea.append("正在上传 " + file.getName() + "\n");
68 | }
69 | // 构造文件名
70 | String fName = file.getName();
71 | if (isRename) {
72 | int pointer = fName.lastIndexOf(".");
73 | if (pointer > -1) {
74 | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HH.mm.ss");
75 | fName = sdf.format(new Date()) + fName.substring(pointer);
76 | System.out.println(fName);
77 | }
78 | }else {
79 | try {
80 | fName = URLEncoder.encode(fName, "UTF-8");
81 | }catch (Exception e) {
82 | e.printStackTrace();
83 | }
84 | }
85 | // 构造url // https://api.github.com/repos/:owner/:repo/contents/:path
86 | String url = String.format("https://api.github.com/repos/%s/%s/contents%s%s", Config.owner, Config.repo,
87 | Config.path, fName);
88 | boolean result = FileUploader.create(url, file, token);
89 | synchronized (count) {
90 | count--;
91 | if (result) {
92 | consoleArea.append("上传成功! " + file.getName() + "\n外链为: \n");
93 | // https://github.com/:owner/:repo/blob/master/:path?raw=true
94 | // https://raw.githubusercontent.com/:owner/:repo/master/:path
95 | String shareLink = String.format("https://raw.githubusercontent.com/%s/%s/master%s%s\n", Config.owner, Config.repo,
96 | Config.path, fName);
97 | consoleArea.append(shareLink);
98 | // shareLink 复制到系统剪贴板
99 | if(count == 0) {
100 | Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
101 | Transferable trans = new StringSelection(shareLink);
102 | clipboard.setContents(trans, null);
103 | }
104 | } else
105 | consoleArea.append("上传失败! " + file.getName() + "\n");
106 | }
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/src/nicelee/github/ui/MainFrame.java:
--------------------------------------------------------------------------------
1 | package nicelee.github.ui;
2 |
3 | import java.awt.Color;
4 | import java.awt.Dimension;
5 | import java.awt.FlowLayout;
6 | import java.awt.Font;
7 | import java.awt.datatransfer.DataFlavor;
8 | import java.awt.dnd.DnDConstants;
9 | import java.awt.dnd.DropTarget;
10 | import java.awt.dnd.DropTargetDragEvent;
11 | import java.awt.dnd.DropTargetDropEvent;
12 | import java.awt.dnd.DropTargetEvent;
13 | import java.awt.dnd.DropTargetListener;
14 | import java.awt.event.ActionEvent;
15 | import java.awt.event.ActionListener;
16 | import java.io.File;
17 | import java.text.SimpleDateFormat;
18 | import java.util.Date;
19 | import java.util.List;
20 |
21 | import javax.swing.BorderFactory;
22 | import javax.swing.ImageIcon;
23 | import javax.swing.JButton;
24 | import javax.swing.JCheckBox;
25 | import javax.swing.JFileChooser;
26 | import javax.swing.JFrame;
27 | import javax.swing.JLabel;
28 | import javax.swing.JScrollPane;
29 | import javax.swing.JTextArea;
30 | import javax.swing.JTextField;
31 |
32 | import nicelee.github.config.Config;
33 | import nicelee.github.runnable.ThUpload;
34 |
35 | public class MainFrame extends JFrame implements ActionListener, DropTargetListener {
36 |
37 | private static final long serialVersionUID = 1L;
38 | private final int HEIGHT = 30;
39 |
40 | // 用于上传的文件选择
41 | static JTextField fileText = new JTextField();
42 | JButton btnFileChooser = new JButton("...");
43 | JLabel dragArea = new JLabel("拖拽文件至此处", JLabel.CENTER);
44 | JButton btnUpload = new JButton("上传");
45 | // 是否自动重命名
46 | JCheckBox isRename = new JCheckBox("按时间重命名");
47 | // 用于输出提示
48 | static JTextArea consoleArea = new JTextArea(12, 50);
49 |
50 | public static void main(String[] args) {
51 | System.out.println(System.getProperty("file.encoding"));
52 | MainFrame log = new MainFrame();
53 | log.InitUI();
54 | Config.readFromFile();
55 | ThUpload.init(Config.token, consoleArea, fileText);
56 | consoleArea.append("owner --> " + Config.owner);
57 | consoleArea.append("\nrepo --> " + Config.repo);
58 | consoleArea.append("\npath --> " + Config.path);
59 | consoleArea.append("\ntoken --> " + Config.token);
60 | consoleArea.append("\n");
61 | }
62 |
63 | public void InitUI() {
64 | // 设置窗口名称
65 | this.setTitle("Github文件上传");
66 | this.setSize(620, 500);
67 | this.setResizable(false);
68 | this.setLocationRelativeTo(null);
69 | this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
70 | ImageIcon icon = new ImageIcon(this.getClass().getResource("/resources/github_logo.png"));
71 | this.setIconImage(icon.getImage());
72 |
73 | // 此处使用流式布局FlowLayout,流式布局类似于word的布局
74 | FlowLayout f1 = new FlowLayout(FlowLayout.LEFT);
75 | // this窗口设置为f1的流式左对齐
76 | this.setLayout(f1);
77 |
78 | /**
79 | * 文件夹选项
80 | */
81 | this.addBlank(40, HEIGHT);
82 | JLabel lbDstFolder = new JLabel("目标文件:");
83 | lbDstFolder.setPreferredSize(new Dimension(80, HEIGHT));
84 | this.add(lbDstFolder);
85 |
86 | fileText.setPreferredSize(new Dimension(270, HEIGHT));
87 | this.add(fileText);
88 |
89 | btnFileChooser.addActionListener(this);
90 | btnFileChooser.setPreferredSize(new Dimension(20, HEIGHT));
91 | this.add(btnFileChooser);
92 |
93 | btnUpload.addActionListener(this);
94 | this.add(btnUpload);
95 |
96 | isRename.setSelected(true);
97 | this.add(isRename);
98 | /**
99 | * dragArea
100 | */
101 | this.addBlank(20, HEIGHT);
102 | dragArea.setBorder(BorderFactory.createLineBorder(Color.red));
103 | dragArea.setPreferredSize(new Dimension(550, 200));
104 | dragArea.setFont(new Font("黑体", Font.BOLD, 50));
105 | this.add(dragArea);
106 | new DropTarget(dragArea, DnDConstants.ACTION_NONE, this);
107 |
108 | /**
109 | * console
110 | */
111 | this.addBlank(20, HEIGHT);
112 | this.addBlank(20, HEIGHT);
113 | consoleArea.setEditable(false);
114 | consoleArea.setLineWrap(true);
115 | JScrollPane js = new JScrollPane(consoleArea);
116 | // 分别设置水平和垂直滚动条出现方式
117 | js.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
118 | js.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
119 | this.add(js);
120 |
121 | this.setVisible(true);
122 | }
123 |
124 | /**
125 | * 增加空白格,用于调整位置
126 | */
127 | private void addBlank(int width, int height) {
128 | JLabel blank = new JLabel();
129 | blank.setPreferredSize(new Dimension(width, height));
130 | // blank.setBorder(BorderFactory.createLineBorder(Color.red));
131 | this.add(blank);
132 | }
133 |
134 | public void actionPerformed(ActionEvent e) {
135 | if (e.getSource() == btnFileChooser) {
136 | JFileChooser fileChooser = null;
137 | String currentFolder = fileText.getText();
138 | File f = new File(currentFolder);
139 | if (f.exists()) {
140 | fileChooser = new JFileChooser(f);
141 | } else {
142 | fileChooser = new JFileChooser(".");
143 |
144 | }
145 | fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
146 | fileChooser.setDialogTitle("请选择文件...");
147 | fileChooser.setApproveButtonText("确定");
148 | fileChooser.showOpenDialog(this);// 显示打开的文件对话框
149 | f = fileChooser.getSelectedFile();// 使用文件类获取选择器选择的文件
150 | if (f != null) {
151 | String s = f.getAbsolutePath();// 返回路径名
152 | fileText.setText(s);
153 | }
154 | }else if(e.getSource() == btnUpload) {
155 | uploadFile(new File(fileText.getText()));
156 | }
157 | }
158 |
159 | @Override
160 | public void dragEnter(DropTargetDragEvent dtde) {
161 | dragArea.setText("松开鼠标上传");
162 | }
163 |
164 | @Override
165 | public void dragOver(DropTargetDragEvent dtde) {
166 |
167 | }
168 |
169 | @Override
170 | public void dropActionChanged(DropTargetDragEvent dtde) {
171 |
172 | }
173 |
174 | @Override
175 | public void dragExit(DropTargetEvent dte) {
176 | dragArea.setText("拖拽文件至此处");
177 | }
178 |
179 | @Override
180 | public void drop(DropTargetDropEvent dtde) {
181 | dragArea.setText("处理中...");
182 | try {
183 | if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
184 | dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);// 接收拖拽来的数据
185 | List list = (List) (dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor));
186 | for (File file : list) {
187 | uploadFile(file);
188 | }
189 |
190 | dtde.dropComplete(true);// 指示拖拽操作已完成
191 | } else {
192 | dtde.rejectDrop();// 否则拒绝拖拽来的数据
193 | }
194 | } catch (Exception e) {
195 | e.printStackTrace();
196 | }
197 | dragArea.setText("拖拽文件至此处");
198 | }
199 |
200 | void uploadFile(File file) {
201 | if (file.isDirectory())
202 | return;
203 | String fName = file.getName();
204 | if (isRename.isSelected()) {
205 | int pointer = fName.lastIndexOf(".");
206 | if(pointer > -1) {
207 | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HH.mm.ss");
208 | fName = sdf.format(new Date()) + fName.substring(pointer);
209 | }
210 | }
211 | ThUpload.addUploadTask(file, isRename.isSelected());
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/src/nicelee/github/upload/FileUploader.java:
--------------------------------------------------------------------------------
1 | package nicelee.github.upload;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.DataOutputStream;
5 | import java.io.File;
6 | import java.io.InputStreamReader;
7 | import java.io.RandomAccessFile;
8 | import java.net.HttpURLConnection;
9 | import java.net.URL;
10 | import java.util.Base64;
11 | import java.util.regex.Matcher;
12 | import java.util.regex.Pattern;
13 |
14 | public class FileUploader {
15 |
16 |
17 | public static void main(String args[]) {
18 | String url = args[0];
19 | File file = new File(args[1]);
20 | String token = args[2];
21 | create(url, file, token);
22 | //update(url, file, token);
23 | }
24 |
25 |
26 | /**
27 | * 由于没有考虑sha,故而只能新建文件,而不能更新文件(更新文件需要先get访问得到sha,然后再put)
28 | *
29 | * @param url https://api.github.com/repos/:owner/:repo/contents/:path
30 | * @param file 需确保文件存在
31 | * @param token 用于鉴权
32 | * @return
33 | */
34 | public static boolean create(String url, File file, String token) {
35 | long begin = System.currentTimeMillis();
36 | System.out.println("上传开始...");
37 | //StringBuffer result = new StringBuffer();
38 | BufferedReader in = null;
39 | HttpURLConnection conn = null;
40 | try {
41 | URL realUrl = new URL(url);
42 | conn = (HttpURLConnection) realUrl.openConnection();
43 | conn.setConnectTimeout(120000);
44 | conn.setReadTimeout(120000);
45 | // 设置
46 | conn.setDoOutput(true); // 需要输出
47 | conn.setDoInput(true); // 需要输入
48 | conn.setUseCaches(false); // 不允许缓存
49 | conn.setRequestMethod("PUT"); // 设置PUT方式连接
50 |
51 | conn.setRequestProperty("Content-Type", "application/json");
52 | conn.setRequestProperty("Authorization", "token " + token);
53 | conn.setRequestProperty("User-Agent", "Github File Uploader App");
54 | conn.connect();
55 | // 传输数据
56 | DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
57 | // 传输json头部
58 | dos.writeBytes("{\"message\":\".\",\"content\":\"");
59 | // 传输文件内容
60 | byte[] buffer = new byte[1024 * 1002]; // 3的倍数
61 | RandomAccessFile raf = new RandomAccessFile(file, "r");
62 | long size = raf.read(buffer);
63 | while (size > -1) {
64 | if (size == buffer.length) {
65 | dos.write(Base64.getEncoder().encode(buffer));
66 | } else {
67 | byte tmp[] = new byte[(int) size];
68 | System.arraycopy(buffer, 0, tmp, 0, (int) size);
69 | dos.write(Base64.getEncoder().encode(tmp));
70 | }
71 | size = raf.read(buffer);
72 | }
73 | raf.close();
74 | // 传输json尾部
75 | dos.writeBytes("\"}");
76 | dos.flush();
77 | dos.close();
78 |
79 | in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
80 | String line;
81 | while ((line = in.readLine()) != null) {
82 | //result.append(line).append("\n");
83 | }
84 | } catch (Exception e) {
85 | System.out.println("发送PUT请求出现异常!");
86 | e.printStackTrace();
87 | return false;
88 | } finally {
89 | try {
90 | in.close();
91 | } catch (Exception e2) {
92 | }
93 | }
94 | long end = System.currentTimeMillis();
95 | System.out.printf("上传结束,耗时 %ds\n", (end - begin) / 1000);
96 | //result.toString()
97 | return true;
98 | }
99 |
100 | /**
101 | * 更新文件(先get访问得到sha,然后再put)
102 | *
103 | * @param url https://api.github.com/repos/:owner/:repo/contents/:path
104 | * @param file 需确保文件存在
105 | * @param token 用于鉴权
106 | * @return
107 | */
108 | public static boolean update(String url, File file, String token) {
109 | long begin = System.currentTimeMillis();
110 | System.out.println("获取文件SHA...");
111 | String sha = getSHA(url);
112 | if(sha == null)
113 | return false;
114 | long end = System.currentTimeMillis();
115 | System.out.printf("获取文件SHA 耗时 %ds\n", (end - begin) / 1000);
116 | System.out.println("上传开始...");
117 | //StringBuffer result = new StringBuffer();
118 | BufferedReader in = null;
119 | HttpURLConnection conn = null;
120 | try {
121 | URL realUrl = new URL(url);
122 | conn = (HttpURLConnection) realUrl.openConnection();
123 | conn.setConnectTimeout(120000);
124 | conn.setReadTimeout(120000);
125 | // 设置
126 | conn.setDoOutput(true); // 需要输出
127 | conn.setDoInput(true); // 需要输入
128 | conn.setUseCaches(false); // 不允许缓存
129 | conn.setRequestMethod("PUT"); // 设置PUT方式连接
130 |
131 | conn.setRequestProperty("Content-Type", "application/json");
132 | conn.setRequestProperty("Authorization", "token " + token);
133 | conn.setRequestProperty("User-Agent", "Github File Uploader App");
134 | conn.connect();
135 | // 传输数据
136 | DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
137 | // 传输json头部
138 | dos.writeBytes("{\"message\":\".\",\"sha\":\"" + sha +"\",\"content\":\"");
139 | // 传输文件内容
140 | byte[] buffer = new byte[1024 * 1002]; // 3的倍数
141 | RandomAccessFile raf = new RandomAccessFile(file, "r");
142 | long size = raf.read(buffer);
143 | while (size > -1) {
144 | if (size == buffer.length) {
145 | dos.write(Base64.getEncoder().encode(buffer));
146 | } else {
147 | byte tmp[] = new byte[(int) size];
148 | System.arraycopy(buffer, 0, tmp, 0, (int) size);
149 | dos.write(Base64.getEncoder().encode(tmp));
150 | }
151 | size = raf.read(buffer);
152 | }
153 | raf.close();
154 | // 传输json尾部
155 | dos.writeBytes("\"}");
156 | dos.flush();
157 | dos.close();
158 |
159 | in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
160 | String line;
161 | while ((line = in.readLine()) != null) {
162 | //result.append(line).append("\n");
163 | }
164 | } catch (Exception e) {
165 | System.out.println("发送PUT请求出现异常!");
166 | e.printStackTrace();
167 | return false;
168 | } finally {
169 | try {
170 | in.close();
171 | } catch (Exception e2) {
172 | }
173 | }
174 | end = System.currentTimeMillis();
175 | System.out.printf("上传结束,耗时 %ds\n", (end - begin) / 1000);
176 | //result.toString()
177 | return true;
178 | }
179 |
180 | /**
181 | * 获取url 对应的SHA
182 | * @param url
183 | * @param token
184 | * @return
185 | */
186 | static Pattern pattern = Pattern.compile("\"sha\": *\"([^\"]+)\"");
187 | public static String getSHA(String url) {
188 | StringBuffer result = new StringBuffer();
189 | BufferedReader in = null;
190 | HttpURLConnection conn = null;
191 | try {
192 | URL realUrl = new URL(url);
193 | conn = (HttpURLConnection) realUrl.openConnection();
194 | conn.setConnectTimeout(120000);
195 | conn.setReadTimeout(120000);
196 | conn.setRequestMethod("GET");
197 | conn.setRequestProperty("User-Agent", "Github File Uploader App");
198 | conn.connect();
199 | in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
200 | String line;
201 | while ((line = in.readLine()) != null) {
202 | result.append(line).append("\n");
203 | }
204 | Matcher matcher = pattern.matcher(result.toString());
205 | if(matcher.find()) {
206 | return matcher.group(1);
207 | }
208 | } catch (Exception e) {
209 | System.out.println("请求SHA出现异常!");
210 | e.printStackTrace();
211 | } finally {
212 | try {
213 | in.close();
214 | } catch (Exception e2) {
215 | }
216 | }
217 | return null;
218 | }
219 |
220 | }
221 |
--------------------------------------------------------------------------------
/src/resources/github_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nICEnnnnnnnLee/FileUploader4Github/3a3eefa90fa1eeec7a587a3b884f3ca76d0fd5de/src/resources/github_logo.png
--------------------------------------------------------------------------------
/src/test/junit/FileUploaderTest.java:
--------------------------------------------------------------------------------
1 | package test.junit;
2 |
3 | import java.io.File;
4 | import java.net.URLEncoder;
5 |
6 | import org.junit.jupiter.api.Test;
7 |
8 | import nicelee.github.upload.FileUploader;
9 |
10 | class FileUploaderTest {
11 |
12 | // @Test
13 | void test() {
14 | String url = "https://api.github.com/repos/nICEnnnnnnnLee/AbcTest/contents/note/test.jpg";
15 | File file = new File(
16 | "D:\\Workspace\\GitWorkspace\\0_GitHub\\nICEnnnnnnnLee.github.io\\sources\\pics\\bg-catoon.jpg");
17 | boolean result = FileUploader.create(url, file, ":token");
18 | System.out.println(result);
19 | }
20 |
21 | //@Test
22 | void testSHA() {
23 | /// repos/:owner/:repo/contents/:path
24 | String url = "https://api.github.com/repos/nICEnnnnnnnLee/AbcTest/contents/note/bg-catoon.jpg";
25 | String result = FileUploader.getSHA(url);
26 | System.out.println(result);
27 | }
28 |
29 | @Test
30 | void testUPDATE() {
31 | String url = "https://api.github.com/repos/nICEnnnnnnnLee/AbcTest/contents/note/test.jpg";
32 | File file = new File(
33 | "D:\\Workspace\\GitWorkspace\\0_GitHub\\nICEnnnnnnnLee.github.io\\sources\\pics\\bg-catoon.jpg");
34 | boolean result = FileUploader.update(url, file, ":token");
35 | System.out.println(result);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------