Compare commits
46 Commits
805e9ef46f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d0af09f86 | |||
| 9b034619a8 | |||
| 6482d52f0b | |||
| cc252a367f | |||
| 186d69cb53 | |||
| fa6b0bad92 | |||
| 14c7249083 | |||
| c5ce1629ef | |||
| 06e2b7c641 | |||
| 04005ea47d | |||
| 1d4b5941e4 | |||
| 20b13af982 | |||
| a024de9165 | |||
| 3034cf8aab | |||
| 3dc9bc1faa | |||
| b09fc1fa19 | |||
| fa4a3bcf88 | |||
| 41b0a3e93b | |||
| f9ee755a29 | |||
| ca7a0c026a | |||
| 7f50b237ae | |||
| 4837c0e628 | |||
| 389c91609a | |||
| b4253d58f1 | |||
| ea21f8bb69 | |||
| 4acdca9c43 | |||
| 596c257b77 | |||
| 5ba89a4019 | |||
| 9238babde7 | |||
| 81bd2e43ed | |||
| 60174e78b8 | |||
| cc18438573 | |||
| 3ab7595d2c | |||
| 71f114a59e | |||
| 510759a005 | |||
| ca09506e7d | |||
| ee29c54eef | |||
| 7f860d0154 | |||
| c434a1d0c1 | |||
| efd334b04b | |||
| a16b75b53a | |||
| b35c267d2f | |||
| 321cb36793 | |||
| b9a925af8e | |||
| 42560051d6 | |||
| b246a56510 |
@@ -3,30 +3,37 @@
|
||||
inputs.handyhelper.url = "../";
|
||||
|
||||
outputs = { self, nixpkgs, handyhelper }: let
|
||||
handy_overlay = (final: prev: {
|
||||
handy_helper = handyhelper.packages."x86_64-linux".default;
|
||||
});
|
||||
system = "x86_64-linux";
|
||||
handy_py = handyhelper.packages.${system}.handyhelper;
|
||||
in {
|
||||
nixosConfigurations."staging" = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
inherit system;
|
||||
modules = [
|
||||
../secrets/config.nix
|
||||
({ config, pkgs, ... }: {
|
||||
nixpkgs.overlays = [
|
||||
handy_overlay
|
||||
];
|
||||
})
|
||||
({lib, config, pkgs, ...}: {
|
||||
../secrets/deploy.nix
|
||||
({lib, config, pkgs, ...}: let
|
||||
in {
|
||||
systemd.services.handyhelper = {
|
||||
wantedBy = ["networking-online.target"];
|
||||
enable = true;
|
||||
path = [
|
||||
pkgs.handy_helper
|
||||
];
|
||||
script = ''
|
||||
${pkgs.handy_helper}/bin/handyhelper.py
|
||||
'';
|
||||
serviceConfig = {
|
||||
WorkingDirectory = config.users.users.handy.home;
|
||||
ExecStart = ''
|
||||
${handy_py}/bin/handyhelper
|
||||
'';
|
||||
User = "handy";
|
||||
RuntimeDirectory = "handyhelper";
|
||||
RuntimeDirectoryMode = "0755";
|
||||
};
|
||||
};
|
||||
users.users = {
|
||||
handy = {
|
||||
home = "/var/lib/handyhelper";
|
||||
useDefaultShell = true;
|
||||
isSystemUser = true;
|
||||
group = "handy";
|
||||
};
|
||||
};
|
||||
users.groups.handy = {};
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
38
flake.nix
38
flake.nix
@@ -11,9 +11,29 @@
|
||||
outputs = { self, nixpkgs, flake-utils, poetry2nix }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
# see https://github.com/nix-community/poetry2nix/tree/master#api for more functions and examples.
|
||||
inherit (poetry2nix.legacyPackages.${system}) mkPoetryApplication mkPoetryEnv;
|
||||
inherit (poetry2nix.legacyPackages.${system}) mkPoetryApplication mkPoetryEnv mkPoetryPackages defaultPoetryOverrides;
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
overrides = defaultPoetryOverrides.extend
|
||||
(self: super: {
|
||||
nextcord = super.nextcord.overridePythonAttrs
|
||||
(
|
||||
old: {
|
||||
propagatedBuildInputs = (
|
||||
old.propagatedBuildInputs or []
|
||||
) ++ [super.setuptools];
|
||||
}
|
||||
);
|
||||
pdftotext = super.pdftotext.overridePythonAttrs
|
||||
(
|
||||
old: {
|
||||
buildInputs = (
|
||||
old.buildInputs or []
|
||||
) ++ (with pkgs; [
|
||||
poppler
|
||||
]);
|
||||
}
|
||||
);
|
||||
});
|
||||
in rec {
|
||||
|
||||
hydraJobs = pkgs.lib.optionalAttrs
|
||||
@@ -44,18 +64,28 @@ DOC
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
packages = {
|
||||
handyhelper = mkPoetryApplication { projectDir = self; };
|
||||
default = self.packages.${system}.myapp;
|
||||
handyhelper = mkPoetryApplication {
|
||||
projectDir = self;
|
||||
# TODO: Upload to poetry2nix
|
||||
# https://github.com/nix-community/poetry2nix/blob/master/docs/edgecases.md
|
||||
inherit overrides;
|
||||
};
|
||||
default = self.packages.${system}.handyhelper;
|
||||
};
|
||||
|
||||
devShells.default = pkgs.mkShell {
|
||||
PYPROJECT_FILE = ./pyproject.toml;
|
||||
packages = with pkgs; [
|
||||
poetry2nix.packages.${system}.poetry
|
||||
(mkPoetryEnv {
|
||||
projectDir = self;
|
||||
inherit overrides;
|
||||
})
|
||||
sops
|
||||
# For pdftotext
|
||||
poppler
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1 +1,103 @@
|
||||
# Handle major modules of package
|
||||
import nextcord as nc
|
||||
from nextcord.ext import commands
|
||||
from typing import Optional
|
||||
import asyncio
|
||||
import io
|
||||
import os
|
||||
import requests as req
|
||||
from bs4 import BeautifulSoup as soup
|
||||
import pdftotext
|
||||
import sys
|
||||
import openai
|
||||
|
||||
openai.api_key = os.getenv("OPENAI_KEY")
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
bot = commands.Bot()
|
||||
|
||||
async def search(txt):
|
||||
url = "https://www.sci-hub.st/"
|
||||
resp = req.post(url, data={
|
||||
'request':txt
|
||||
})
|
||||
|
||||
doc = soup(resp.text, 'html.parser')
|
||||
|
||||
if 'not found' in doc.find('title').get_text():
|
||||
return None
|
||||
|
||||
ref = doc.find('div', {'id': 'citation'}).get_text()
|
||||
pdf = doc.find('embed', {'id': 'pdf'})['src']
|
||||
|
||||
pdf = pdf[:(pdf.find(".pdf")+4)]
|
||||
|
||||
return {
|
||||
'ref': ref,
|
||||
'pdf': f"https:{pdf}"
|
||||
}
|
||||
|
||||
async def getPDF(url):
|
||||
eprint(f"Fetching PDF: {url}")
|
||||
resp = req.get(url, stream=True)
|
||||
pdf = io.BytesIO(resp.content)
|
||||
pages = pdftotext.PDF(pdf)
|
||||
|
||||
with open("./test.txt","w") as f:
|
||||
f.write("\n\n".join(pages))
|
||||
|
||||
return "\n\n".join(pages)
|
||||
|
||||
async def summarize(pdf):
|
||||
completion = openai.ChatCompletion.create(
|
||||
model="gpt-3.5-turbo",
|
||||
messages=[
|
||||
{"role": "user", "content": f"""Please summarize the following research paper:
|
||||
---
|
||||
{pdf}
|
||||
"""}
|
||||
],
|
||||
user="HandyHelper"
|
||||
)
|
||||
|
||||
eprint(completion.usage)
|
||||
|
||||
return completion.choices[0].message
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
print(f'We have logged in as {bot.user}')
|
||||
|
||||
@bot.slash_command(name="summarize", description="Summarize all or part of an article", dm_permission=True)
|
||||
async def summarize(
|
||||
interaction: nc.Interaction,
|
||||
article: str,
|
||||
part: Optional[str] = nc.SlashOption(required=False)
|
||||
):
|
||||
await interaction.response.defer(ephemeral=False, with_message=True)
|
||||
|
||||
resp = await search(article)
|
||||
|
||||
if resp is None:
|
||||
await interaction.followup.send(f"Unable to find article: {article}")
|
||||
return
|
||||
|
||||
msg = await interaction.followup.send(f"""Article Found: {resp['ref']}
|
||||
Processing PDF...""")
|
||||
pdf = await getPDF(resp['pdf'])
|
||||
|
||||
await msg.edit(f"""Article Found: {resp['ref']}
|
||||
```
|
||||
{pdf[:1000]}
|
||||
```""")
|
||||
|
||||
def main():
|
||||
# TODO: Import bot token from env
|
||||
bot.run(os.environ["DISCORD_TOKEN"])
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Handy Helper has Begun!")
|
||||
main()
|
||||
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import nextcord
|
||||
from nextcord.ext import commands
|
||||
import os
|
||||
|
||||
bot = commands.Bot()
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
print(f'We have logged in as {bot.user}')
|
||||
|
||||
@bot.slash_command(name="summarize", description="Summarize all or part of an article", dm_permission=True)
|
||||
async def summarize(
|
||||
interaction: nextcord.Interaction,
|
||||
article: str,
|
||||
part: Optional[str] = SlashOption(required=False)
|
||||
):
|
||||
print("Will summarize article.")
|
||||
|
||||
# TODO: Import bot token from env
|
||||
bot.run(os.environ["DISCORD_TOKEN"],)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Handy Helper has Begun!")
|
||||
90
poetry.lock
generated
90
poetry.lock
generated
@@ -197,6 +197,25 @@ files = [
|
||||
{file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "beautifulsoup4"
|
||||
version = "4.11.2"
|
||||
description = "Screen-scraping library"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6.0"
|
||||
files = [
|
||||
{file = "beautifulsoup4-4.11.2-py3-none-any.whl", hash = "sha256:0e79446b10b3ecb499c1556f7e228a53e64a2bfcebd455f370d8927cb5b59e39"},
|
||||
{file = "beautifulsoup4-4.11.2.tar.gz", hash = "sha256:bc4bdda6717de5a2987436fb8d72f45dc90dd856bdfd512a1314ce90349a0106"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
soupsieve = ">1.2"
|
||||
|
||||
[package.extras]
|
||||
html5lib = ["html5lib"]
|
||||
lxml = ["lxml"]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2022.12.7"
|
||||
@@ -298,7 +317,7 @@ files = [
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "dev"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
files = [
|
||||
@@ -619,6 +638,29 @@ docs = ["sphinx (==5.2.3)", "sphinxcontrib-websupport", "sphinxcontrib_trio (==1
|
||||
speed = ["aiohttp[speedups]", "orjson (>=3.5.4)"]
|
||||
voice = ["PyNaCl (>=1.3.0,<1.5)"]
|
||||
|
||||
[[package]]
|
||||
name = "openai"
|
||||
version = "0.27.2"
|
||||
description = "Python client library for the OpenAI API"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7.1"
|
||||
files = [
|
||||
{file = "openai-0.27.2-py3-none-any.whl", hash = "sha256:6df674cf257e9e0504f1fd191c333d3f6a2442b13218d0eccf06230eb24d320e"},
|
||||
{file = "openai-0.27.2.tar.gz", hash = "sha256:5869fdfa34b0ec66c39afa22f4a0fb83a135dff81f6505f52834c6ab3113f762"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
aiohttp = "*"
|
||||
requests = ">=2.20"
|
||||
tqdm = "*"
|
||||
|
||||
[package.extras]
|
||||
datalib = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"]
|
||||
dev = ["black (>=21.6b0,<22.0)", "pytest (>=6.0.0,<7.0.0)", "pytest-asyncio", "pytest-mock"]
|
||||
embeddings = ["matplotlib", "numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "plotly", "scikit-learn (>=1.0.2)", "scipy", "tenacity (>=8.0.1)"]
|
||||
wandb = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "wandb"]
|
||||
|
||||
[[package]]
|
||||
name = "parso"
|
||||
version = "0.8.3"
|
||||
@@ -635,6 +677,17 @@ files = [
|
||||
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
|
||||
testing = ["docopt", "pytest (<6.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pdftotext"
|
||||
version = "2.2.2"
|
||||
description = "Simple PDF text extraction"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "pdftotext-2.2.2.tar.gz", hash = "sha256:2a9aa89bc62022408781b39d188fabf5a3ad1103b6630f32c4e27e395f7966ee"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pexpect"
|
||||
version = "4.8.0"
|
||||
@@ -838,6 +891,18 @@ files = [
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "soupsieve"
|
||||
version = "2.4"
|
||||
description = "A modern CSS selector implementation for Beautiful Soup."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "soupsieve-2.4-py3-none-any.whl", hash = "sha256:49e5368c2cda80ee7e84da9dbe3e110b70a4575f196efb74e51b94549d921955"},
|
||||
{file = "soupsieve-2.4.tar.gz", hash = "sha256:e28dba9ca6c7c00173e34e4ba57448f0688bb681b7c5e8bf4971daafc093d69a"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stack-data"
|
||||
version = "0.6.2"
|
||||
@@ -858,6 +923,27 @@ pure-eval = "*"
|
||||
[package.extras]
|
||||
tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"]
|
||||
|
||||
[[package]]
|
||||
name = "tqdm"
|
||||
version = "4.65.0"
|
||||
description = "Fast, Extensible Progress Meter"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"},
|
||||
{file = "tqdm-4.65.0.tar.gz", hash = "sha256:1871fb68a86b8fb3b59ca4cdd3dcccbc7e6d613eeed31f4c332531977b89beb5"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
|
||||
[package.extras]
|
||||
dev = ["py-make (>=0.1.0)", "twine", "wheel"]
|
||||
notebook = ["ipywidgets (>=6)"]
|
||||
slack = ["slack-sdk"]
|
||||
telegram = ["requests"]
|
||||
|
||||
[[package]]
|
||||
name = "traitlets"
|
||||
version = "5.9.0"
|
||||
@@ -1081,4 +1167,4 @@ multidict = ">=4.0"
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "92d541073d72547903239effa9d265802ef82c24f4207c0af3202e27d37954f6"
|
||||
content-hash = "37cd0a0c44f8d8dc60f31db3cd1c01303d4ca07f85282c6a1823ed8135714313"
|
||||
|
||||
@@ -6,10 +6,16 @@ authors = ["David Crompton"]
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
handyhelper = "handyhelper:main"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
requests = "^2.28.2"
|
||||
nextcord = "^2.4.1"
|
||||
openai = "^0.27.2"
|
||||
beautifulsoup4 = "^4.11.2"
|
||||
pdftotext = "^2.2.2"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
ipython = "^8.11.0"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:8YOc0g12Wq25MvgPN0jAvGQObdmmPs9ipchVjChr0DfnD724mpuMgiaLEiQti4RFLHDM7rg0jNJq8zileFxSTdC8MND0i0tEMM81oIV6p+L+5yf6vQqQ/aDTFRs0NdbPLMYjd5meVzUy6x5PhbBznJfdf7ZOxpri0s6PKtdCNV88Soxukwzp8Mf4MPUFtvYrvqjq+GrM7aVJU/nj9ZUzlmHsz32gpLhoO9AYXSJ2W3Se9zuP+S3QDS5RtRLTCLgzXF7n9KidGRRZrpI+lNA9J9Di80DDJ9Nd+AGO7/8W8UZYlQMVkKRXtNt+AWtXalzKaHl8ftIEfsgWe3Z6VtboaxJZ5EFweSxgjXjLdLtDUA9wnhHN7nAFaCBdE/91o/zhKjtzAisXBvf7kMStWkyxsBmEqjnNelDVLtqKAkOBNcq8cRr8YOF3Vyt1vBAXPz32h3mXTQXO8UNzE/pyl7Anny/eHXWT2tZXxxA=,iv:c3fb4wkWkqCfFthX+tYuWhVjSvIve3A5/5p1znI1164=,tag:pXtwwJnr9hvXOIwB9Wt99w==,type:str]",
|
||||
"data": "ENC[AES256_GCM,data:wepRFTHhHt4vBz1ZTNUB0m4ECBvHEf7U7sCBNptuxzMX3xpk2Hrk9Cde4OT02UdNnaTSz0h4OANNh/2945CbRl87sFhR2/DY+P21LD240lhbWCgrbSUKgHjI0d+PyC0npOCv2+2cglJn+OsgYe4rrZlA8g6AbRejTJjnc5+jIDkj9VMX2TZCATuIRg2+8aHYr4tNq5Mfd4Y0OnF+VmQH/SDeap1YeUhh1l/6UEiuUrB4RvH+oNtZaDdDLI4Cg6sKXAeFcx8jejtYu59NDv4TiFi6EDZ4/WflWCvTuUqmG7qv8aBcKCK2tIfLPM6POD614I76v/suelZ+pSP0ij4UfC374tIB3CcO3v6MJpj3gwHz9+fomuYq4TC1g5moaVO2OU7oGfEIo5kKCeJpQX8o+qUjwZzpvP0y906Ow7tpBKZr2Se/w1k+IL0ZfzEtRhqN84M/U17pk+Yo0X5DzwLvPRc8rrUMmUNAUqv7W4cN13zakXaWhBBSkVwRnW2raJnW+u5Gd9l4UYz0QY1SpItC49Rm5zOsFWwt92BjV+LLT8pIiRsdDkevTuGuHVAyK3PAixNMPqMJ,iv:5gCuJnHiRVqb8wLgTgY74DbH6CYpmcXIlYBvne7sYF0=,tag:7eVarvHuNk3y3zHc8sDjTQ==,type:str]",
|
||||
"sops": {
|
||||
"kms": null,
|
||||
"gcp_kms": null,
|
||||
@@ -15,8 +15,8 @@
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtVWpxVTB3N2xpcXpDWlhI\naHM1TW9LL1FnT2lkRGF2bFM5VEVkNzRCV1djCkFqcmRLeWhYRkE0NzkvU00xcGdG\nYlpFOTlzWm9GS1BERi93QkxzOTJVN0EKLS0tIHpOYnlqMW9zaFpWaTJza2EzV1Jx\nOE1CUENlZlVKbGt6dUJUdUJuL1JmclkKFXf8F6bNDNDRpo+0X2MJKxAFls1vp/tr\n09dMExuNCHwJayKXlIL5+3OMDFTrjz49gZFQpWaOgQUbCVpI2Tff/A==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2023-03-15T23:27:35Z",
|
||||
"mac": "ENC[AES256_GCM,data:kIWZqNDaAp0jxyFpVUzncM7AAm3u05V+FZrinZ95ftjV3ja9aLp8Ha1BVjg4csI8Yqk8Uc6IFXv9pnm6CnD2nWwPe2+W28hnIwP4B8SkiAoXj9dOT8gw5S+Vw0w8NoLFEGZ90xaiDdG5kfQCep9g4zWbqBHg397h1fxrTGJw5B8=,iv:An/IWRopuQ1RRSMgeXJcJuoL81SUtI8IsvY8asR984k=,tag:pLqRzKMv2VGWNCR8iOeskQ==,type:str]",
|
||||
"lastmodified": "2023-03-18T03:32:23Z",
|
||||
"mac": "ENC[AES256_GCM,data:cajh/+/3udzyWXaUMgcshsfsZ9WnLOCuFu3g/Dbu3riEARGuDf7vWEOFnjJbOvBwyXJ3Vcq7KaoB9x7vKC7vnNs982ffuvhxZTHyNEOs21UZB5IGszj0UCuXnHQJ+qMXVGYbFRU00KXh8e3bMwEe71fPq1iLLLFx82dllNl4Lng=,iv:oAvZNEYWASq+2v0O6ZP56EVI9YrjTeaDhUpcWEGiCE8=,tag:+E0fz422Axr996NBzcm4tg==,type:str]",
|
||||
"pgp": null,
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.7.3"
|
||||
|
||||
Reference in New Issue
Block a user