• 基于flask和fomantic-ui的简易p2p文件分享平台的手动实现


    背景

    开学一个多月了,由于繁重的学业和懒惰,都没怎么更新有意思的博客。

    前几天突然想到了一个想法。同学之间平常用网络分享一个文件,大部分都是用的qq。但是qq看起来把文件拖到聊天框点击发送就发给对面同学了。但是实际上是先上传到了腾讯的服务器,然后对面的同学再从服务器上下载。

    这一上传一下载就很耽误时间。我就想在我的电脑上开一个文件上传服务,别的同学直接上传到我的机械革命上,上传完毕,我就得到了这个文件,不用再下载一遍。而且由于是校园网内的服务,速度也有保障。

    语言选择

    由于前几天做了几道python flask模板注入的题目,便打算拿flask来当后端练练手,提供http服务。

    前端的话还是利用漂亮且方便易用的fomantic-ui解决html和css样式问题,再配合上大大简化js编程的Jquery来写效果和功能。

    遇到的困难

    单纯的文件上传十分简单。对付小文件还好,但是大文件就会出现页面停滞的情况,而用户收不到任何反馈,不知道到底是在上传还是崩溃了。我们需要设置一个上传进度条来给以用户友善的提示。所以这里就有一个问题,如何获得上传的进度?

    查询资料过后,我发现XMLHttpRequest能够获取进度。然后我又发现Jquery中封装的$.ajax能够更加简单的实现。参考链接 https://stackoverflow.com/questions/13203231/is-there-any-way-to-get-jquery-ajax-upload-progress

    代码

    文件目录

    文件目录

    文件目录

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf8" />
    5. <script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js">script>
    6. <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.8.8/dist/semantic.min.css" />
    7. <script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.8.8/dist/semantic.min.js">script>
    8. <title>wuuconix's pagetitle>
    9. head>
    10. <body>
    11. <div style="padding-top: 5em;">div>
    12. <div class="ui text container">
    13. <div class="ui placeholder segment">
    14. {% if filelist == [] %}
    15. <div class="ui icon header">
    16. <i class="pdf file outline icon">i>
    17. 目前文件夹里空空如也
    18. div>
    19. {% else %}
    20. <div class="ui list">
    21. {% for file in filelist%}
    22. <div class="item">
    23. <i class="file icon">i>
    24. <div class="content">
    25. <a class="header" href="download/{{file}}" data-content="点击下载{{file}}" id="files">{{file}}a>
    26. div>
    27. div>
    28. {% endfor %}
    29. div>
    30. {% endif %}
    31. <div class="ui buttons">
    32. <button class="ui primary button" id="button_choose">选择文件button>
    33. <button class="ui positive button" id="button_submit">上传button>
    34. div>
    35. <form action="/upload" method="post" enctype="multipart/form-data" id="form">
    36. <input type="file" id="input_file" style="display: none;" name="file">
    37. form>
    38. <div class="ui divider">div>
    39. <div class="ui indicating progress" id="progress" data-value="0" data-total="100">
    40. <div class="bar">
    41. <div class="progress">div>
    42. div>
    43. <div class="label">div>
    44. div>
    45. div>
    46. div>
    47. body>
    48. <script>
    49. $(document).ready(function(){
    50. $("#progress").hide();
    51. $("#button_submit").attr("disabled", true);
    52. });
    53. $("#button_choose").click(function()
    54. {
    55. $("#input_file").click();
    56. });
    57. $("#input_file").bind("input propertychange",function(){
    58. var name = ($(this).prop('files')[0]['name']);
    59. $("#button_submit").attr("disabled", false);
    60. $('#button_choose')[0].innerHTML=name;
    61. });
    62. $("#button_submit").click(function()
    63. {
    64. $("#progress").show();
    65. var formdata = new FormData($("#form")[0]);
    66. $.ajax({
    67. url:'/upload',
    68. type:'post',
    69. xhr: function () {
    70. var xhr = $.ajaxSettings.xhr();
    71. var starttime = Math.ceil(new Date().getTime() / 1000);
    72. xhr.upload.onprogress = function (e) {
    73. if (e.lengthComputable) {
    74. var uploaded = Math.ceil(e.loaded / Math.pow(1024,2));
    75. var spenttime = Math.ceil(new Date().getTime() / 1000) - starttime;
    76. var speed = (uploaded / spenttime).toFixed(2);
    77. var progress = Math.ceil(e.loaded / e.total * 100);
    78. $("#progress").attr('data-value', progress);
    79. $("#progress").progress('update progress', progress);
    80. $("#progress").progress('set label', speed + "MB/s");
    81. }
    82. };
    83. return xhr;
    84. },
    85. processData:false,
    86. contentType:false,
    87. data:formdata,
    88. success:function (data) {
    89. $('body').toast({
    90. title: '恭喜你',
    91. message: "你已经成功将 《" + $('#button_choose')[0].innerHTML + "》 上传至了武丑兄的机械革命。页面即将自动刷新",
    92. showProgress: 'bottom',
    93. classProgress: 'red'
    94. });
    95. setTimeout("location.reload();", 3000)
    96. }
    97. })
    98. });
    99. $('#progress').progress({
    100. label: 'percent',
    101. });
    102. $('a').popup({
    103. on: 'hover'
    104. });
    105. $("#button_submit").popup({
    106. on: 'hover'
    107. });
    108. script>
    1. from flask import render_template, Flask, request, make_response, send_from_directory
    2. import os
    3. def get_filelist():
    4. filelist = os.listdir("upload/")
    5. return filelist
    6. app = Flask(__name__)
    7. @app.route('/')
    8. def hello(filelist=[]):
    9. return render_template("index.html", filelist=get_filelist())
    10. @app.route('/upload',methods=['GET','POST'])
    11. def upload():
    12. if request.method == 'POST':
    13. f = request.files['file']
    14. print(request.files)
    15. f.save(f"upload/{f.filename}")
    16. filelist = get_filelist()
    17. return render_template("index.html", filelist=filelist)
    18. else:
    19. return render_template("index.html", filelist=get_filelist())
    20. @app.route('/download/',methods=['GET'])
    21. def download(filename):
    22. response = make_response(send_from_directory("upload", filename, as_attachment=True))
    23. response.headers["Content-Disposition"] = "attachment; filename={}".format(filename.encode().decode('latin-1'))
    24. return response
    25. if __name__ == '__main__':
    26. app.run(host='0.0.0.0', port=80)

    效果

    界面

    界面

    界面

    上传1

    上传1

    上传2

    上传2

    上传3

    上传3

    转载申明

    本文转载自腾讯博客,转载请注明出处:365文档网

  • 相关阅读:
    八大排序算法-直接插入排序、希尔排序、直接选择排序、冒泡排序、堆排序、快速排序、归并排序、基数排序(下)
    前端培训丁鹿学堂:vue3之watchEffect和生命周期函数总结
    CF427D. Match & Catch 后缀数组 计数
    智慧办公前沿 10月24日OffiSmart峰会深圳站议程揭晓
    不只有 Spring,这四款 Java 基础开发框架同样值得关注!
    java--拼图游戏
    生命不息,分享不止,5款小巧的免费软件
    使用JDBC连接DM8数据库(ODBC连接DM8数据库)
    Java中的类加载器双亲委派模型机制
    面试题:jwt 是什么?java-jwt 呢?
  • 原文地址:https://blog.csdn.net/sonsunny/article/details/134415770