mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2024-11-22 11:18:08 -06:00
Added OCR support via the ocr.space API. Closes #93
This commit is contained in:
parent
516acb501a
commit
ec58d02bb3
@ -10,6 +10,7 @@
|
||||
* Retweets should be displayed normally again when the originating tweet is a Twishort's long tweet.
|
||||
* Changed the way TWBlue saves user timelines in configuration. Now it uses user IDS instead usernames. With user IDS, if an user changes the username, TWBlue still will create his/her timeline. This was not possible by using usernames.
|
||||
* Added a new setting in the account settings dialogue that makes TWBlue to show twitter usernames instead the full name.
|
||||
* Added OCR in twitter pictures. There is a new item in the tweet menu that allows you to extract and display text in images. Also the keystroke alt+Win+o has been added for the same purpose from the invisible interface.
|
||||
|
||||
## Changes in version 0.87
|
||||
|
||||
|
@ -129,6 +129,7 @@ Visually, Towards the top of the main application window, can be found a menu ba
|
||||
* Show tweet: opens up a dialogue box where you can read the tweet, direct message, friend or follower which has focus. You can read the text with the arrow keys. It's a similar dialog box as used for composing tweets, without the ability to send the tweet, file attachment and autocompleting capabilities. It does however include a retweets and favourites count. If you are in the followers or the friends list, it will only contain a read-only edit box with the information in the focused item and a close button.
|
||||
* View address: If the selected tweet has geographical information, TWBlue may display a dialogue box where you can read the tweet address. This address is retrieved by sending the geographical coordinates of the tweet to Google maps.
|
||||
* View conversation: If you are focusing a tweet with a mention, it opens a buffer where you can view the whole conversation.
|
||||
* Read text in pictures: Attempt to apply OCR technology to the image attached to the tweet. The result will be displayed in another dialog.
|
||||
* Delete: permanently removes the tweet or direct message which has focus from Twitter and from your lists. Bear in mind that Twitter only allows you to delete tweets you have posted yourself.
|
||||
|
||||
##### User menu
|
||||
@ -254,6 +255,7 @@ The invisible interface of TWBlue can be customised by using a keymap. Every key
|
||||
* Control + Windows + Shift + G: Display the tweet's geolocation in a dialogue.
|
||||
* Control + Windows + T: Create a trending topics' buffer.
|
||||
* Control + Windows + {: Find a string in the current buffer.
|
||||
* Alt + Windows + O: Extracts text from the picture and display the result in a dialog.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
@ -6,7 +6,7 @@ if system == "Windows":
|
||||
from update import updater
|
||||
from wxUI import (view, dialogs, commonMessageDialogs, sysTrayIcon)
|
||||
import settings
|
||||
from extra import SoundsTutorial
|
||||
from extra import SoundsTutorial, ocr
|
||||
import keystrokeEditor
|
||||
from keyboard_handler.wx_handler import WXKeyboardHandler
|
||||
import userActionsController
|
||||
@ -142,7 +142,7 @@ class Controller(object):
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.find, menuitem=self.view.find)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.accountConfiguration, menuitem=self.view.account_settings)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.configuration, menuitem=self.view.prefs)
|
||||
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.ocr_image, menuitem=self.view.ocr)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.learn_sounds, menuitem=self.view.sounds_tutorial)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.exit, menuitem=self.view.close)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.CLOSE_EVENT, self.exit)
|
||||
@ -1520,6 +1520,32 @@ class Controller(object):
|
||||
buffer_index = self.view.search(buffer.name, buffer.account)
|
||||
self.view.set_page_title(buffer_index, title)
|
||||
|
||||
def ocr_image(self, *args, **kwargs):
|
||||
buffer = self.get_current_buffer()
|
||||
if hasattr(buffer, "get_right_tweet") == False:
|
||||
output.speak(_(u"Invalid buffer"))
|
||||
return
|
||||
tweet = buffer.get_right_tweet()
|
||||
if tweet.has_key("entities") == False or tweet["entities"].has_key("media") == False:
|
||||
output.speak(_(u"This tweet doesn't contain images"))
|
||||
return
|
||||
if len(tweet["entities"]["media"]) > 1:
|
||||
image_list = [_(u"Picture {0}").format(i,) for i in xrange(0, len(tweet["entities"]["media"]))]
|
||||
dialog = dialogs.urlList.urlList(title=_(u"Select the picture"))
|
||||
if dialog.get_response() == widgetUtils.OK:
|
||||
img = tweet["entities"]["media"][dialog.get_item()]
|
||||
else:
|
||||
return
|
||||
else:
|
||||
img = tweet["entities"]["media"][0]
|
||||
api = ocr.OCRSpace.OCRSpaceAPI()
|
||||
try:
|
||||
text = api.OCR_URL(img["media_url"])
|
||||
except ocr.OCRSpace.APIError as er:
|
||||
output.speak(_(u"Unable to extract text"))
|
||||
return
|
||||
msg = messages.viewTweet(text["ParsedText"], [], False)
|
||||
|
||||
def save_data_in_db(self):
|
||||
for i in session_.sessions:
|
||||
session_.sessions[i].shelve()
|
37
src/extra/ocr/OCRSpace.py
Normal file
37
src/extra/ocr/OCRSpace.py
Normal file
@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
""" original module taken and modified from https://github.com/ctoth/cloudOCR"""
|
||||
import requests
|
||||
|
||||
class APIError(Exception):
|
||||
pass
|
||||
|
||||
class OCRSpaceAPI(object):
|
||||
|
||||
def __init__(self, key="4e72ae996f88957", url='https://api.ocr.space/parse/image'):
|
||||
self.key = key
|
||||
self.url = url
|
||||
|
||||
def OCR_URL(self, url, overlay=False):
|
||||
payload = {
|
||||
'url': url,
|
||||
'isOverlayRequired': overlay,
|
||||
'apikey': self.key,
|
||||
}
|
||||
r = requests.post(self.url, data=payload)
|
||||
result = r.json()['ParsedResults'][0]
|
||||
if result['ErrorMessage']:
|
||||
raise APIError(result['ErrorMessage'])
|
||||
return result
|
||||
|
||||
def OCR_file(self, fileobj, overlay=False):
|
||||
payload = {
|
||||
'isOverlayRequired': overlay,
|
||||
'apikey': self.key,
|
||||
'lang': 'es',
|
||||
}
|
||||
r = requests.post(self.url, data=payload, files={'file': fileobj})
|
||||
results = r.json()['ParsedResults']
|
||||
if results[0]['ErrorMessage']:
|
||||
raise APIError(results[0]['ErrorMessage'])
|
||||
return results
|
||||
|
2
src/extra/ocr/__init__.py
Normal file
2
src/extra/ocr/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import OCRSpace
|
@ -53,4 +53,5 @@ check_for_updates = string(default="alt+win+u")
|
||||
list_manager = string(default="alt+win+shift+l")
|
||||
configuration = string(default="control+win+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+alt+shift+u")
|
||||
update_buffer = string(default="control+alt+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
@ -54,4 +54,5 @@ check_for_updates = string(default="control+win+u")
|
||||
list_manager = string(default="control+win+shift+l")
|
||||
configuration = string(default="control+win+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+win+shift+u")
|
||||
update_buffer = string(default="control+win+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
@ -52,4 +52,5 @@ actions = {
|
||||
"accountConfiguration": _(u"Opens the account settings dialogue"),
|
||||
"audio": _(u"Try to play an audio file"),
|
||||
"update_buffer": _(u"Updates the buffer and retrieves possible lost items there."),
|
||||
"ocr_image": _(u"Extracts the text from a picture and displays the result in a dialog."),
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
import wx
|
||||
|
||||
class urlList(wx.Dialog):
|
||||
def __init__(self):
|
||||
super(urlList, self).__init__(parent=None, title=_(u"Select URL"))
|
||||
def __init__(self, title=_(u"Select URL")):
|
||||
super(urlList, self).__init__(parent=None, title=title)
|
||||
panel = wx.Panel(self)
|
||||
self.lista = wx.ListBox(panel, -1)
|
||||
self.lista.SetFocus()
|
||||
|
@ -32,6 +32,7 @@ class mainFrame(wx.Frame):
|
||||
self.view = tweet.Append(wx.NewId(), _(u"&Show tweet"))
|
||||
self.view_coordinates = tweet.Append(wx.NewId(), _(u"View &address"))
|
||||
self.view_conversation = tweet.Append(wx.NewId(), _(u"View conversa&tion"))
|
||||
self.ocr = tweet.Append(wx.NewId(), _(u"Read text in pictures"))
|
||||
self.delete = tweet.Append(wx.NewId(), _(u"&Delete"))
|
||||
|
||||
# User menu
|
||||
|
Loading…
Reference in New Issue
Block a user