Portierung folgender Plugins:

- App Store
- Bitly
- Bitly_create
- Expand
- Facebook
- GitHub
This commit is contained in:
Andreas Bielawski 2016-06-15 18:00:59 +02:00
parent 4a21409bd6
commit 4a6b9b1816
7 changed files with 611 additions and 0 deletions

View File

@ -0,0 +1,117 @@
local app_store = {}
local https = require('ssl.https')
local json = require('dkjson')
local utilities = require('otouto.utilities')
local redis = (loadfile "./otouto/redis.lua")()
app_store.triggers = {
"itunes.apple.com/(.*)/app/(.*)/id(%d+)",
"^!itunes (%d+)$",
"itunes.apple.com/app/id(%d+)"
}
local BASE_URL = 'https://itunes.apple.com/lookup'
local makeOurDate = function(dateString)
local pattern = "(%d+)%-(%d+)%-(%d+)T"
local year, month, day = dateString:match(pattern)
return day..'.'..month..'.'..year
end
function app_store:get_appstore_data()
local url = BASE_URL..'/?id='..appid..'&country=de'
local res,code = https.request(url)
if code ~= 200 then return "HTTP-FEHLER" end
local data = json.decode(res).results[1]
if data == nil then return 'NOTFOUND' end
if data.wrapperType ~= 'software' then return nil end
return data
end
function app_store:send_appstore_data(data)
-- Header
local name = data.trackName
local author = data.sellerName
local price = data.formattedPrice
local version = data.version
-- Body
local description = string.sub(unescape(data.description), 1, 150) .. '...'
local min_ios_ver = data.minimumOsVersion
local size = string.gsub(round(data.fileSizeBytes / 1000000, 2), "%.", ",") -- wtf Apple, it's 1024, not 1000!
local release = makeOurDate(data.releaseDate)
if data.isGameCenterEnabled then
game_center = '\nUnterstützt Game Center'
else
game_center = ''
end
local category_count = tablelength(data.genres)
if category_count == 1 then
category = '\nKategorie: '..data.genres[1]
else
local category_loop = '\nKategorien: '
for v in pairs(data.genres) do
if v < category_count then
category_loop = category_loop..data.genres[v]..', '
else
category_loop = category_loop..data.genres[v]
end
end
category = category_loop
end
-- Footer
if data.averageUserRating and data.userRatingCount then
avg_rating = 'Bewertung: '..string.gsub(data.averageUserRating, "%.", ",")..' Sterne '
ratings = 'von '..comma_value(data.userRatingCount)..' Bewertungen'
else
avg_rating = ""
ratings = ""
end
local header = '*'..name..'* v'..version..' von *'..author..'* ('..price..'):'
local body = '\n'..description..'\n_Benötigt mind. iOS '..min_ios_ver..'_\nGröße: '..size..' MB\nErstveröffentlicht am '..release..game_center..category
local footer = '\n'..avg_rating..ratings
local text = header..body..footer
-- Picture
if data.screenshotUrls[1] and data.ipadScreenshotUrls[1] then
image_url = data.screenshotUrls[1]
elseif data.screenshotUrls[1] and not data.ipadScreenshotUrls[1] then
image_url = data.screenshotUrls[1]
elseif not data.screenshotUrls[1] and data.ipadScreenshotUrls[1] then
image_url = data.ipadScreenshotUrls[1]
else
image_url = nil
end
return text, image_url
end
function app_store:action(msg, config, matches)
if not matches[3] then
appid = matches[1]
else
appid = matches[3]
end
local data = app_store:get_appstore_data()
if data == nil then print('Das Appstore-Plugin unterstützt nur Apps!') end
if data == 'HTTP-FEHLER' or data == 'NOTFOUND' then
utilities.send_reply(self, msg, '*App nicht gefunden!*', true)
return
else
local output, image_url = app_store:send_appstore_data(data)
utilities.send_reply(self, msg, output, true)
if image_url then
utilities.send_typing(self, msg.chat.id, 'upload_photo')
local file = download_to_file(image_url)
utilities.send_photo(self, msg.chat.id, file, nil, msg.message_id)
end
end
end
return app_store

48
otouto/plugins/bitly.lua Normal file
View File

@ -0,0 +1,48 @@
local bitly = {}
local https = require('ssl.https')
local json = require('dkjson')
local utilities = require('otouto.utilities')
local redis = (loadfile "./otouto/redis.lua")()
function bitly:init(config)
if not cred_data.bitly_access_token then
print('Missing config value: bitly_access_token.')
print('bitly.lua will not be enabled.')
return
end
bitly.triggers = {
"bit.ly/([A-Za-z0-9-_-]+)",
"bitly.com/([A-Za-z0-9-_-]+)",
"j.mp/([A-Za-z0-9-_-]+)",
"andib.tk/([A-Za-z0-9-_-]+)"
}
end
local BASE_URL = 'https://api-ssl.bitly.com/v3/expand'
function bitly:expand_bitly_link (shorturl)
local access_token = cred_data.bitly_access_token
local url = BASE_URL..'?access_token='..access_token..'&shortUrl=https://bit.ly/'..shorturl
local res,code = https.request(url)
if code ~= 200 then return "HTTP-FEHLER" end
local data = json.decode(res).data.expand[1]
cache_data('bitly', shorturl, data)
return data.long_url
end
function bitly:action(msg, config, matches)
local shorturl = matches[1]
local hash = 'telegram:cache:bitly:'..shorturl
if redis:exists(hash) == false then
utilities.send_reply(self, msg, bitly:expand_bitly_link(shorturl))
return
else
local data = redis:hgetall(hash)
utilities.send_reply(self, msg, data.long_url)
return
end
end
return bitly

View File

@ -0,0 +1,142 @@
local bitly_create = {}
local http = require('socket.http')
local https = require('ssl.https')
local URL = require('socket.url')
local json = require('dkjson')
local utilities = require('otouto.utilities')
local bindings = require('otouto.bindings')
local OAuth = require "OAuth"
local redis = (loadfile "./otouto/redis.lua")()
function bitly_create:init(config)
if not cred_data.bitly_client_id then
print('Missing config value: bitly_client_id.')
print('bitly_create.lua will not be enabled.')
return
elseif not cred_data.bitly_client_secret then
print('Missing config value: bitly_client_secret.')
print('bitly_create.lua will not be enabled.')
return
elseif not cred_data.bitly_redirect_uri then
print('Missing config value: bitly_redirect_uri.')
print('bitly_create.lua will not be enabled.')
return
end
bitly_create.triggers = {
"^/short (auth) (.+)$",
"^/short (auth)$",
"^/short (unauth)$",
"^/short (me)$",
"^/short (j.mp) (https?://[%w-_%.%?%.:/%+=&]+)$",
"^/short (bit.ly) (https?://[%w-_%.%?%.:/%+=&]+)$",
"^/short (bitly.com) (https?://[%w-_%.%?%.:/%+=&]+)$",
"^/short (https?://[%w-_%.%?%.:/%+=&]+)$"
}
bitly_create.doc = [[*
]]..config.cmd_pat..[[short* _<Link>_: Kürzt einen Link mit der Standard Bitly-Adresse
*]]..config.cmd_pat..[[short* _<j.mp|bit.ly|bitly.com>_ _[Link]_: Kürzt einen Link mit der ausgewählten Kurz-URL
*]]..config.cmd_pat..[[short* _auth_: Loggt deinen Account ein und nutzt ihn für deine Links (empfohlen!)
*]]..config.cmd_pat..[[short* _me_: Gibt den eingeloggten Account aus
*]]..config.cmd_pat..[[short* _unauth_: Loggt deinen Account aus
]]
end
bitly_create.command = 'short <URL>'
local BASE_URL = 'https://api-ssl.bitly.com'
local client_id = cred_data.bitly_client_id
local client_secret = cred_data.bitly_client_secret
local redirect_uri = cred_data.bitly_redirect_uri
function bitly_create:get_bitly_access_token(hash, code)
local req = post_petition(BASE_URL..'/oauth/access_token', 'client_id='..client_id..'&client_secret='..client_secret..'&code='..code..'&redirect_uri='..redirect_uri)
if not req.access_token then return '*Fehler beim Einloggen!*' end
local access_token = req.access_token
local login_name = req.login
redis:hset(hash, 'bitly', access_token)
return 'Erfolgreich als `'..login_name..'` eingeloggt!'
end
function bitly_create:get_bitly_user_info(bitly_access_token)
local url = BASE_URL..'/v3/user/info?access_token='..bitly_access_token..'&format=json'
local res,code = https.request(url)
if code == 401 then return 'Login fehlgeschlagen!' end
if code ~= 200 then return 'HTTP-Fehler!' end
local data = json.decode(res).data
if data.full_name then
name = '*'..data.full_name..'* (`'..data.login..'`)'
else
name = '`'..data.login..'`'
end
local text = 'Eingeloggt als '..name
return text
end
function bitly_create:create_bitlink (long_url, domain, bitly_access_atoken)
local url = BASE_URL..'/v3/shorten?access_token='..bitly_access_token..'&domain='..domain..'&longUrl='..long_url..'&format=txt'
local text,code = https.request(url)
if code ~= 200 then return 'FEHLER: '..text end
return text
end
function bitly_create:action(msg, config, matches)
local hash = 'user:'..msg.from.id
bitly_access_token = redis:hget(hash, 'bitly')
if matches[1] == 'auth' and matches[2] then
utilities.send_reply(self, msg, bitly_create:get_bitly_access_token(hash, matches[2]), true)
return
end
if matches[1] == 'auth' then
utilities.send_reply(self, msg, 'Bitte logge dich ein und folge den Anweisungen:\n[Bei Bitly anmelden](https://bitly.com/oauth/authorize?client_id='..client_id..'&redirect_uri='..redirect_uri..')', true)
return
end
if matches[1] == 'unauth' and bitly_access_token then
redis:hdel(hash, 'bitly')
utilities.send_reply(self, msg, '*Erfolgreich ausgeloggt!* Du kannst den Zugriff [in deinen Kontoeinstellungen](https://bitly.com/a/settings/connected) endgültig entziehen.', true)
return
elseif matches[1] == 'unauth' and not bitly_access_token then
utilities.send_reply(self, msg, 'Wie willst du dich ausloggen, wenn du gar nicht eingeloggt bist?', true)
return
end
if matches[1] == 'me' and bitly_access_token then
local text = bitly_create:get_bitly_user_info(bitly_access_token)
if text then
utilities.send_reply(self, msg, text, true)
return
else
return
end
elseif matches[1] == 'me' and not bitly_access_token then
utilities.send_reply(self, msg, 'Du bist nicht eingeloggt! Logge dich ein mit\n/short auth', true)
return
end
if not bitly_access_token then
print('Not signed in, will use global bitly access_token')
bitly_access_token = cred_data.bitly_access_token
end
if matches[2] == nil then
long_url = url_encode(matches[1])
domain = 'bit.ly'
else
long_url = url_encode(matches[2])
domain = matches[1]
end
utilities.send_reply(self, msg, bitly_create:create_bitlink(long_url, domain, bitly_access_token))
return
end
return bitly_create

37
otouto/plugins/expand.lua Normal file
View File

@ -0,0 +1,37 @@
local expand = {}
local http = require('socket.http')
local utilities = require('otouto.utilities')
function expand:init(config)
expand.triggers = {
"^/expand (https?://[%w-_%.%?%.:/%+=&]+)$"
}
expand.doc = [[*
]]..config.cmd_pat..[[expand* _<Kurz-URL>_: Verlängert Kurz-URL (301er/302er)]]
end
expand.command = 'expand <Kurz-URL>'
function expand:action(msg, config, matches)
local response_body = {}
local request_constructor = {
url = matches[1],
method = "HEAD",
sink = ltn12.sink.table(response_body),
headers = {},
redirect = false
}
local ok, response_code, response_headers, response_status_line = http.request(request_constructor)
if ok and response_headers.location then
utilities.send_reply(self, msg, response_headers.location)
return
else
utilities.send_reply(self, msg, "Fehler beim Erweitern der URL.")
return
end
end
return expand

180
otouto/plugins/facebook.lua Normal file
View File

@ -0,0 +1,180 @@
local facebook = {}
local http = require('socket.http')
local https = require('ssl.https')
local URL = require('socket.url')
local json = require('dkjson')
local utilities = require('otouto.utilities')
local bindings = require('otouto.bindings')
local redis = (loadfile "./otouto/redis.lua")()
function facebook:init(config)
if not cred_data.fb_access_token then
print('Missing config value: fb_access_token.')
print('facebook.lua will not be enabled.')
return
end
facebook.triggers = {
"facebook.com/([A-Za-z0-9-._-]+)/(posts)/(%d+)",
"facebook.com/(permalink).php%?(story_fbid)=(%d+)&id=(%d+)",
"facebook.com/(photo).php%?fbid=(%d+)",
"facebook.com/([A-Za-z0-9-._-]+)/(photos)/a.(%d+[%d%.]*)/(%d+)",
"facebook.com/(video).php%?v=(%d+)",
"facebook.com/([A-Za-z0-9-._-]+)/(videos)/(%d+[%d%.]*)",
"facebook.com/([A-Za-z0-9-._-]+)"
}
end
local BASE_URL = 'https://graph.facebook.com/v2.5'
local fb_access_token = cred_data.fb_access_token
local makeOurDate = function(dateString)
local pattern = "(%d+)%/(%d+)%/(%d+)"
local month, day, year = dateString:match(pattern)
return day..'.'..month..'.'..year
end
function facebook:get_fb_id(name)
local url = BASE_URL..'/'..name..'?access_token='..fb_access_token..'&locale=de_DE'
local res,code = https.request(url)
if code ~= 200 then return nil end
local data = json.decode(res)
return data.id
end
function facebook:fb_post (id, story_id)
local url = BASE_URL..'/'..id..'_'..story_id..'?access_token='..fb_access_token..'&locale=de_DE&fields=from,name,story,message,link'
local res,code = https.request(url)
if code ~= 200 then return nil end
local data = json.decode(res)
local from = data.from.name
local message = data.message
local name = data.name
if data.link then
link = '\n'..data.name..':\n'..data.link
else
link = ""
end
if data.story then
story = ' ('..data.story..')'
else
story = ""
end
local text = '*'..from..'*'..story..':\n'..message..'\n'..link
return text
end
function facebook:send_facebook_photo(photo_id, receiver)
local url = BASE_URL..'/'..photo_id..'?access_token='..fb_access_token..'&locale=de_DE&fields=images,from,name'
local res,code = https.request(url)
if code ~= 200 then return nil end
local data = json.decode(res)
local from = '*'..data.from.name..'*'
if data.name then
text = from..' hat ein Bild gepostet:\n'..data.name
else
text = from..' hat ein Bild gepostet:'
end
local image_url = data.images[1].source
return text, image_url
end
function facebook:send_facebook_video(video_id)
local url = BASE_URL..'/'..video_id..'?access_token='..fb_access_token..'&locale=de_DE&fields=description,from,source,title'
local res,code = https.request(url)
if code ~= 200 then return nil end
local data = json.decode(res)
local from = '*'..data.from.name..'*'
local description = data.description
local source = data.source
if data.title then
text = from..' hat ein Video gepostet:\n'..description..'\n['..data.title..']('..source..')'
else
text = from..' hat ein Video gepostet:\n'..description..'\n'..utilities.md_escape(source)
end
return text
end
function facebook:facebook_info(name)
local url = BASE_URL..'/'..name..'?access_token='..fb_access_token..'&locale=de_DE&fields=about,name,birthday,category,founded,general_info,is_verified'
local res,code = https.request(url)
if code ~= 200 then return nil end
local data = json.decode(res)
local name = data.name
if data.is_verified then
name = name..''
end
local category = data.category
if data.about then
about = '\n'..data.about
else
about = ""
end
if data.general_info then
general_info = '\n'..data.general_info
else
general_info = ""
end
if data.birthday and data.founded then
birth = '\nGeburtstag: '..makeOurDate(data.birthday)
elseif data.birthday and not data.founded then
birth = '\nGeburtstag: '..makeOurDate(data.birthday)
elseif data.founded and not data.birthday then
birth = '\nGegründet: '..data.founded
else
birth = ""
end
local text = '*'..name..'* ('..category..')_'..about..'_'..general_info..birth
return text
end
function facebook:action(msg, config, matches)
if matches[1] == 'permalink' or matches[2] == 'posts' then
story_id = matches[3]
if not matches[4] then
id = facebook:get_fb_id(matches[1])
else
id = matches[4]
end
utilities.send_reply(self, msg, facebook:fb_post(id, story_id), true)
return
elseif matches[1] == 'photo' or matches[2] == 'photos' then
if not matches[4] then
photo_id = matches[2]
else
photo_id = matches[4]
end
utilities.send_typing(self, msg.chat.id, 'upload_photo')
local text, image_url = facebook:send_facebook_photo(photo_id, receiver)
local file = download_to_file(image_url)
utilities.send_reply(self, msg, text, true)
utilities.send_photo(self, msg.chat.id, file, nil, msg.message_id)
return
elseif matches[1] == 'video' or matches[2] == 'videos' then
if not matches[3] then
video_id = matches[2]
else
video_id = matches[3]
end
local output = facebook:send_facebook_video(video_id)
utilities.send_reply(self, msg, output, true)
return
else
utilities.send_reply(self, msg, facebook:facebook_info(matches[1]), true)
return
end
end
return facebook

77
otouto/plugins/github.lua Normal file
View File

@ -0,0 +1,77 @@
local github = {}
local http = require('socket.http')
local https = require('ssl.https')
local URL = require('socket.url')
local json = require('dkjson')
local utilities = require('otouto.utilities')
local bindings = require('otouto.bindings')
local redis = (loadfile "./otouto/redis.lua")()
function github:init(config)
github.triggers = {
"github.com/([A-Za-z0-9-_-.-._.]+)/([A-Za-z0-9-_-.-._.]+)/commit/([a-z0-9-]+)",
"github.com/([A-Za-z0-9-_-.-._.]+)/([A-Za-z0-9-_-.-._.]+)/?$"
}
end
local BASE_URL = 'https://api.github.com'
function github:get_gh_data(gh_code, gh_commit_sha)
if gh_commit_sha == nil then
url = BASE_URL..'/repos/'..gh_code
else
url = BASE_URL..'/repos/'..gh_code..'/git/commits/'..gh_commit_sha
end
local res,code = https.request(url)
if code ~= 200 then return "HTTP-FEHLER" end
local data = json.decode(res)
return data
end
function github:send_github_data(data)
if not data.owner then return nil end
local name = '*'..data.name..'*'
local description = '_'..data.description..'_'
local owner = data.owner.login
local clone_url = data.clone_url
if data.language == nil or data.language == "" then
language = ''
else
language = '\nSprache: '..data.language
end
if data.open_issues_count == 0 then
issues = ''
else
issues = '\nOffene Bugreports: '..data.open_issues_count
end
if data.homepage == nil or data.homepage == "" then
homepage = ''
else
homepage = '\n[Homepage besuchen]('..data.homepage..')'
end
local text = name..' von '..owner..'\n'..description..'\n`git clone '..clone_url..'`'..language..issues..homepage
return text
end
function github:send_gh_commit_data(gh_code, gh_commit_sha, data)
if not data.committer then return nil end
local committer = data.committer.name
local message = data.message
local text = '`'..gh_code..'@'..gh_commit_sha..'` von *'..committer..'*:\n'..message
return text
end
function github:action(msg, config, matches)
local gh_code = matches[1]..'/'..matches[2]
local gh_commit_sha = matches[3]
local data = github:get_gh_data(gh_code, gh_commit_sha)
if not gh_commit_sha then
output = github:send_github_data(data)
else
output = github:send_gh_commit_data(gh_code, gh_commit_sha, data)
end
utilities.send_reply(self, msg, output, true)
end
return github

View File

@ -821,4 +821,14 @@ function unescape(str)
return str return str
end end
function url_encode(str)
if (str) then
str = string.gsub (str, "\n", "\r\n")
str = string.gsub (str, "([^%w %-%_%.%~])",
function (c) return string.format ("%%%02X", string.byte(c)) end)
str = string.gsub (str, " ", "+")
end
return str
end
return utilities return utilities