草庐IT

用ChatGPT+Copilot一小时开发一套监控系统

浮肿前行 2023-05-15 原文

套娃:我把下面的内容全部复制给了ChatGPT,让它帮我总结本文内容,它的回答如下:

本文介绍了人工智能ChatGPT在快速生成代码方面的应用,以及当前AI从专业客户走向大众、从特定领域走向通用领域、从后台走向前台和人的直接交互等趋势。文中展示了一些场景下AI助手的应用案例,包括辅助查找视频资料、整理出视频摘要、使用微软的new Bing快速获取高精度内容等。随后,介绍了通过ChatGPT生成程序的方法,包括编写截屏程序和编写fastapi服务。最后,文中针对问题进行了详细的解答。

背景

从去年ChatGPT上线开始就时不时的把玩,不经感叹划时代的通用AI真的就这么诞生了!它的功能实在是太强大了,配合一些工具、准确恰当的提问,真的可以帮你巨大的提升效率。

  • 这次通过ChatGPT,快速生成了适用于三个程序,虽然功能很简单,但是通过对话,它能很好的帮你生成需要的功能的代码
  • 有了代码,接着就是检查错误,修改参数
  • 配合Copilot,原本100行代码假设需要100分钟,现在一半以上的场景可能只需要按一下Tab键,效率简直炸裂!

介于下面都是问题和代码,先草草来两句总结:

  • 目前AI正在从专业客户走向大众,从特定领域走向通用领域,从后台走向前台和人的直接交互
  • 最近市面上涌现出了多个可用的、效果惊人的AI应用,举个例子:AI向我介绍了一些咨询,我根据咨询查找了一些视频资料,但是视频太长我没时间看,所以将链接发给了AI,AI帮我整理出了summary,summary太长,AI帮我精简出了要点,然后如果有问题的话,AI会根据里面的内容回答我。
  • 微软的new Bing是搜索进化后的新形态
  • 原本人们沉浸在海量内容中,但是有人会困惑于如何快速获取高精度内容,现在有了答案
  • 现在的场景是:顶级AI助手

效果图:

绿色的按钮是设备名称,点击按钮可以弹窗显示缩略图对应的原图

话不多说,先来看一下需求和设计的功能:

事前准备

问ChatGPT的问题

①写终端的截屏程序

问题:

帮我用python写一个程序。该程序可以每隔5分钟截取windows桌面的图片,并通过post方法传输出去。

补充问题:

  1. 根据这个生产截屏的python程序,再重写一下fastapi的服务
  2. 帮我根据上面的upload_image接口改造对应的一开始截屏程序的请求参数
import time
import requests
from PIL import ImageGrab
import socket
from datetime import datetime

hostname = socket.gethostname()

while True:
    # 截屏
    img = ImageGrab.grab()  # 截取屏幕截图
    img.save('screenshot.png')  # 将截图保存到本地

    data = {
            'name': hostname,
            'updateTime': datetime.now().strftime('-%m%d-%H%M')
            }
    files = {'image': (open('screenshot.png', 'rb'))}
    # 发送 POST 请求
    url = 'http://localhost:8000/upload_image'
    response = requests.post(url, data=data, files=files)

    # 处理响应
    if response.status_code == 200:
        print('Image uploaded successfully!')
    else:
        print('Failed to upload image.')
        # 休眠 5 分钟
    time.sleep(300)
②写服务端

问题:

然后再用fastapi写一个服务。首先我有一个配置文件,用来管理几十台设备,这个配置文件里含有每台设备的name。然后构建一个post接口,用来接收post请求,接收的内容是一张图片,接收成功后将图片保存到本地的capture文件夹中,并将图片再生成一张宽度为400的缩略图,保持宽高比不变。再构建一个get接口,当接收到get请求后,将capture文件夹下所有的缩略图返回。最后再构建一个get接口,请求参数是name,capture下图片文件名是name的原始图片返回。

补充问题:

  1. /get_images这个接口是返回所有的缩略图文件,帮忙改一下
  2. 请将/get_image/{name} 路由改为使用base64.b64encode将图片文件转换成Base64编码的字符串
  3. /get_images这个接口改为返回图片,而不是图片名称
  4. 帮我再补一段python代码,判断capture目录下是否有相同name的图片,如果有的话删除
import base64
from fastapi import FastAPI, File, Form, UploadFile
from fastapi.responses import FileResponse
import os
import time
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from pathlib import Path


app = FastAPI()

# 2、声明一个 源 列表;重点:要包含跨域的客户端 源
origins = ["*", "./*"]

# 3、配置 CORSMiddleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,  # 允许访问的源
    allow_credentials=True,  # 支持 cookie
    allow_methods=["*"],  # 允许使用的请求方法
    allow_headers=["*"]  # 允许携带的 Headers
)


def delete_if_exist(name):
    folder_path = "./capture"
    for file_name in os.listdir(folder_path):
        if file_name.startswith(name):
            file_path = os.path.join(folder_path, file_name)
            os.remove(file_path)


@app.post("/upload_image")
async def upload_image(image: UploadFile = File(...), name: str = Form(...), updateTime: str = Form(...)):
    # save the original image to the capture folder
    file_path = f"./capture/{name}{updateTime}.png"
    delete_if_exist(name)
    with open(file_path, "wb") as f:
        f.write(await image.read())

    # generate thumbnail
    from PIL import Image
    img = Image.open(file_path)
    width, height = img.size
    thumbnail_size = (400, int(height * 400 / width))
    img.thumbnail(thumbnail_size)
    thumbnail_path = f"./capture/{name}{updateTime}_thumbnail.png"
    img.save(thumbnail_path)

    return {"message": "Image uploaded successfully!"}


@app.get("/get_images")
async def get_images():
    thumbnail_folder = Path("capture")
    thumbnail_files = thumbnail_folder.glob("*_thumbnail.png")
    images = []
    for thumbnail_file in thumbnail_files:
        with open(thumbnail_file, "rb") as f:
            thumbnail = base64.b64encode(f.read()).decode("utf-8")
            image_name = thumbnail_file.stem.replace("_thumbnail", "")
            images.append({"name": image_name, "thumbnail": thumbnail})
    return JSONResponse(content=images)


@app.get("/get_image/{name}")
def get_image(name: str):
    # print(f"capture/{name}.png")
    with open(f"capture/{name}.png", "rb") as f:
        image_bytes = f.read()
    base64_bytes = base64.b64encode(image_bytes)
    base64_string = base64_bytes.decode("utf-8")
    return {"image": base64_string}


③写用户端

问题:

接着我要用html写一个静态页面,该页面使用Materialize这个样式库。整个页面每隔5分钟请求上面的get_images接口获取所有的缩略图,和每个缩略图的名称,将这些图片放到页面上的grid里,整个grid每行有6格,每个格子里上面有一行标题代表缩略图的名称,下面显示缩略图。如果点击缩略图的话,请求上面的/get_image/{name}接口,获取原图,然后弹窗显示

补充问题:

  1. 再将JavaScript的showImage方法改一下
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>j截屏展示窗</title>
    <!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"> -->
    <link rel="stylesheet" href="materialize/css/materialize.min.css">
    <style>
        .modal {
            width: 95%;
            height: 100%;
        }
    </style>
</head>

<body>
    <div class="container">
        <!-- <h3>Image Gallery</h3> -->
        <div class="row" id="grid"></div>
    </div>

    <div id="modal" class="modal">
        <div class="modal-content" id="modal-content"></div>
        <!-- <div class="modal-footer">
        <a href="#!" class="modal-close waves-effect waves-green btn-flat">Close</a>
      </div> -->
    </div>

    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src="materialize/js/materialize.min.js"></script>
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script> -->
    <script>
        function showImage(name) {
            fetch(`http://localhost:8000/get_image/${name}`)
                .then(response => response.json())
                .then(data => {
                    var image = document.createElement('img');
                    image.src = "data:image/jpeg;base64," + data.image;
                    var modalContent = document.getElementById("modal-content");
                    modalContent.innerHTML = '';
                    modalContent.appendChild(image);
                    var modalInstance = M.Modal.getInstance(document.getElementById("modal"));
                    modalInstance.open();
                });
        }

        function updateGrid() {
            fetch('http://localhost:8000/get_images')
                .then(response => response.json())
                .then(data => {
                    var images = data;
                    var grid = document.getElementById('grid');
                    grid.innerHTML = '';

                    for (var i = 0; i < images.length; i++) {
                        var image = images[i];
                        var col = document.createElement('div');
                        col.classList.add('col', 's12', 'm6', 'l3');

                        var card = document.createElement('div');
                        card.classList.add('card', 'hoverable');

                        var cardImage = document.createElement('div');
                        cardImage.classList.add('card-image');
                        var title = document.createElement('span');
                        title.classList.add('card-title');
                        title.innerText = image.name;
                        var thumbnail = document.createElement('img');
                        thumbnail.classList.add('thumbnail');
                        thumbnail.src = "data:image/jpeg;base64," + image.thumbnail;
                        cardImage.appendChild(title);
                        cardImage.appendChild(thumbnail);
                        card.appendChild(cardImage);

                        var cardAction = document.createElement('div');
                        cardAction.classList.add('card-action');
                        cardAction.style.textAlign = 'center';
                        var link = document.createElement('a');
                        link.classList.add('waves-effect', 'waves-light', 'btn');
                        link.innerText = image.name;
                        link.onclick = (function (name) {
                            return function () {
                                showImage(name);
                            };
                        })(image.name);
                        cardAction.appendChild(link);
                        card.appendChild(cardAction);

                        col.appendChild(card);
                        grid.appendChild(col);
                    }
                });
        }

        $(document).ready(function () {
            $('.modal').modal();
            setInterval(updateGrid, 5000);
            updateGrid();
        });
    </script>
</body>

</html>

Done!

有关用ChatGPT+Copilot一小时开发一套监控系统的更多相关文章

  1. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  2. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  3. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  4. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  5. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  6. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  7. 亚特兰蒂斯的回声(中文版): chatGPT 的杰作 - 2

    英文版英文链接关注公众号在“亚特兰蒂斯的回声”中踏上一段难忘的冒险之旅,深入未知的海洋深处。足智多谋的考古学家AriaSeaborne偶然发现了一件古代神器,揭示了一张通往失落之城亚特兰蒂斯的隐藏地图。在她神秘的导师内森·兰登教授的指导和勇敢的冒险家亚历克斯·默瑟的帮助下,阿丽亚开始了一段危险的旅程,以揭开这座传说中城市的真相。他们的冒险之旅带领他们穿越险恶的大海、神秘的岛屿和充满陷阱和谜语的致命迷宫。随着Aria潜在的魔法能力的觉醒,她被睿智勇敢的QueenNeria的幻象所指引,她让她为即将到来的挑战做好准备。三人组揭开亚特兰蒂斯令人惊叹的隐藏文明,并了解到邪恶的巫师马拉卡勋爵试图利用其古

  8. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  9. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  10. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

随机推荐