Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add integration of raycast and wox #149

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions integration/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Integration

Integrations for [Raycast](https://www.raycast.com/) on macOS and [Wox](https://github.com/Wox-launcher/Wox) on Windows.

Currently, the integration use the api hosted on your local machine or a remote server.

## Usage

1. You need to run the LatexOCR api on your local machine on a remote server via:

```bash
python -m pix2tex.api.run
```

2. Install the dependencies with:

```bash
pip install pyperclip pillow requests
```

3. Edit the `API_URL` in [latex2ocr_remote.py](raycast/latex2ocr_remote.py) for macOS, and [main.py](Wox.Plugin.LatexOCR/main.py) for Windows.
4. Install the plugin according to the tutorial of Raycast or Wox.

## Preview

### Raycast on macOS

![raycast preview](https://zeqiang-lai.github.io/blog/docs/imgs/raycast.gif)

### Wox on Windows

![wox preview](https://zeqiang-lai.github.io/blog/docs/imgs/wox.gif)
Binary file added integration/Wox.Plugin.LatexOCR/Images/app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions integration/Wox.Plugin.LatexOCR/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Wox.Plugin.LatexOCR

Latex OCR plugin for Wox.

## Ackowledgements

- [Wox](https://github.com/Wox-launcher/Wox)
- [LaTeX-OCR](https://github.com/lukas-blecher/LaTeX-OCR)
- [wox-python-plugins](https://github.com/jianbing/wox-python-plugins)
49 changes: 49 additions & 0 deletions integration/Wox.Plugin.LatexOCR/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from util import WoxEx, WoxAPI, load_module

with load_module():
import pyperclip
import io
import requests
from PIL import ImageGrab

# replace the address of your remote server
API_URL = 'http://127.0.0.1:8502/predict/'

def latex_ocr_from_clipboard(im):

imbytes = io.BytesIO()
im.save(imbytes, format='png')

response = requests.post(API_URL, files={'file': imbytes.getvalue()})
latex_code = response

return latex_code.json()


class Main(WoxEx):

def query(self, keyword):
results = list()
im = ImageGrab.grabclipboard()
results.append({
"Title": "LatexOCR",
"SubTitle": "No image founded in clipboard" if im is None else "Ready to OCR",
"IcoPath": "Images/ico.ico",
"JsonRPCAction": {
"method": "test_func",
"parameters": [keyword],
"dontHideAfterAction": False # 运行后是否隐藏Wox窗口
}
})
return results

def test_func(self, keyword):
im = ImageGrab.grabclipboard()
if im:
out = latex_ocr_from_clipboard(im)
pyperclip.copy(out)
else:
pyperclip.copy("No image founded in clipboard. Please copy an image to clipboard or take a screen shot first.")

if __name__ == "__main__":
Main()
12 changes: 12 additions & 0 deletions integration/Wox.Plugin.LatexOCR/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"ID":"D2D2C23BFF4D411DB66FEFF79D6C2A6H",
"ActionKeyword":"ocr",
"Name":"LatexOCR",
"Description":"Convert image into latex code",
"Author":"Zeqiang Lai",
"Version":"1.0.0",
"Language":"python",
"Website":"http://www.getwox.com", //插件网站或者个人网站
"IcoPath": "Images\\app.png",
"ExecuteFileName":"main.py"
}
58 changes: 58 additions & 0 deletions integration/Wox.Plugin.LatexOCR/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
from wox import Wox, WoxAPI
import types
import traceback
import logging
import functools
import os
from contextlib import contextmanager

logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename="error.log",
filemode='a')

class Log:
@classmethod
def debug(cls, msg):
logging.debug(msg)

@classmethod
def info(cls, msg):
logging.info(msg)

@classmethod
def error(cls, msg):
logging.error(msg)

@contextmanager
def load_module():
try:
yield
except:
Log.error(traceback.format_exc())
os.system(r'explorer "{}"'.format(os.getcwd()))

def _debug(func):
@functools.wraps(func)
def wrap(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
error = traceback.format_exc()
WoxAPI.show_msg("error", error)
Log.error(error)
os.system(r'explorer "{}"'.format(os.getcwd()))

return wrap

class _DebugMeta(type):
def __new__(cls, clsname, bases, attrs):
for func_name, func in attrs.items():
if isinstance(func, types.FunctionType):
attrs[func_name] = _debug(func)
return super(_DebugMeta, cls).__new__(cls, clsname, bases, attrs)

class WoxEx(Wox, metaclass=_DebugMeta):
pass
41 changes: 41 additions & 0 deletions integration/raycast/latex2ocr_remote.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env python3
# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title latex2ocr_remote
# @raycast.mode compact

# Optional parameters:
# @raycast.icon 🤖

import io

import pyperclip
import requests
from PIL import ImageGrab

# replace the address of your remote server
API_URL = 'http://127.0.0.1:8502/predict/'


def latex2ocr_remote():
im = ImageGrab.grabclipboard()

if im != None:
print('Read image from clipboard')
imbytes = io.BytesIO()

im.save(imbytes, format='png')
print('Convert to bytes')

response = requests.post(API_URL, files={'file': imbytes.getvalue()})
latex_code = response
print(latex_code.json())

pyperclip.copy(latex_code.json())
print('Results copied to clipboard.')
else:
print('No Image in Clipboard')


if __name__ == "__main__":
latex2ocr_remote()
Empty file added pix2tex/api/__init__.py
Empty file.
11 changes: 7 additions & 4 deletions pix2tex/api/run.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from multiprocessing import Process
import subprocess
import os
import sys


def start_api(path='.'):
subprocess.call(['uvicorn', 'app:app', '--port', '8502'], cwd=path)
def start_api(path='.', public=False):
cmd = ['uvicorn', 'app:app', '--port', '8502']
if public: cmd += ['--host', '0.0.0.0']
subprocess.call(cmd, cwd=path)


def start_frontend(path='.'):
Expand All @@ -13,7 +15,8 @@ def start_frontend(path='.'):

if __name__ == '__main__':
path = os.path.realpath(os.path.dirname(__file__))
api = Process(target=start_api, kwargs={'path': path})
public = len(sys.argv) > 1 and sys.argv[1] == 'public'
api = Process(target=start_api, kwargs={'path': path, 'public': public})
api.start()
frontend = Process(target=start_frontend, kwargs={'path': path})
frontend.start()
Expand Down