You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
4.6 KiB
Python
120 lines
4.6 KiB
Python
#! /usr/bin/env python3
|
|
"""
|
|
meli - sample plugin
|
|
|
|
Copyright 2019 Manos Pitsidianakis
|
|
|
|
This file is part of meli.
|
|
|
|
meli is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
meli is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with meli. If not, see <http://www.gnu.org/licenses/>.
|
|
"""
|
|
|
|
import sys
|
|
import time
|
|
import subprocess
|
|
import msgpack
|
|
import nntplib
|
|
import libmeliapi
|
|
import itertools
|
|
|
|
def chunks(iterable, n):
|
|
while True:
|
|
try:
|
|
yield itertools.chain((next(iterable),), itertools.islice(iterable, n-1))
|
|
except:
|
|
break
|
|
|
|
class NNTPClient(libmeliapi.Client):
|
|
def __init__(self, stream_address, server_address, newsgroup):
|
|
super().__init__(stream_address)
|
|
self.bytes_cache = {}
|
|
self.conn = nntplib.NNTP(server_address)
|
|
self.newsgroup = newsgroup
|
|
def backend_req(self, req):
|
|
print("[nntp-plugin]: backend_req = ", req, flush=True, file=sys.stderr)
|
|
if req.data == b'is_online':
|
|
self.ok_send(None)
|
|
elif req.data == b'get':
|
|
resp, count, first, last, name = self.conn.group(self.newsgroup)
|
|
print('Group', name, 'has', count, 'articles, range', first, 'to', last, flush=True, file=sys.stderr)
|
|
|
|
resp, overviews = self.conn.over((0, last))
|
|
for chunk in chunks(iter(reversed(overviews)), 100):
|
|
ret = []
|
|
for id, over in chunk:
|
|
#print(id, nntplib.decode_header(over['subject']), flush=True, file=sys.stderr)
|
|
env = {}
|
|
env["hash"] = id
|
|
env["subject"] = nntplib.decode_header(over["subject"])
|
|
env["from"] = nntplib.decode_header(over["from"])
|
|
env["date"] = nntplib.decode_header(over["date"])
|
|
env["message_id"] = nntplib.decode_header(over["message-id"])
|
|
env["references"] = nntplib.decode_header(over["references"])
|
|
try:
|
|
env["to"] = nntplib.decode_header(over["to"])
|
|
except KeyError:
|
|
env["to"] = self.newsgroup
|
|
ret.append(env)
|
|
print("ret len = ", len(ret), flush=True,file=sys.stderr)
|
|
self.ok_send(ret)
|
|
self.ok_send(None)
|
|
def backend_op_req(self, req):
|
|
print("[nntp-plugin]: backend_op_req = ", req, flush=True, file=sys.stderr)
|
|
if req.data == b'as_bytes':
|
|
_hash = self.read()
|
|
print("[nntp-plugin]: hash = ", _hash, flush=True, file=sys.stderr)
|
|
self.ack()
|
|
try:
|
|
try:
|
|
self.ok_send(self.bytes_cache[_hash])
|
|
except KeyError:
|
|
resp, info = self.conn.article(_hash)
|
|
#print(_id, " line0 = ", str(info.lines[0], 'utf-8', 'ignore'))
|
|
elem = b'\n'.join(info.lines)
|
|
self.bytes_cache[_hash] = str(elem, 'utf-8', 'ignore')
|
|
self.ok_send(self.bytes_cache[_hash])
|
|
except Exception as e:
|
|
self.err_send(str(e))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import importlib
|
|
importlib.reload(libmeliapi)
|
|
stream_address = './soworkfile'
|
|
server_address = 'news.gmane.org'
|
|
newsgroup = 'gmane.comp.python.committers'
|
|
client = NNTPClient(stream_address, server_address, newsgroup)
|
|
client.connect()
|
|
#client.setblocking(True)
|
|
try:
|
|
while True:
|
|
req = client.read()
|
|
if req is None:
|
|
time.sleep(0.15)
|
|
continue
|
|
#client.setblocking(True)
|
|
client.ack()
|
|
print("[nntp-plugin]: ", "req: ", req, flush=True, file=sys.stderr)
|
|
sys.stderr.flush()
|
|
if isinstance(req, msgpack.ExtType):
|
|
if req.code == client.backend_fn_type:
|
|
client.backend_req(req)
|
|
elif req.code == client.backend_op_fn_type:
|
|
client.backend_op_req(req)
|
|
print("[nntp-plugin]: ", req, flush=True, file=sys.stderr)
|
|
#client.setblocking(True)
|
|
time.sleep(0.15)
|
|
except:
|
|
raise RuntimeError("Something bad happened")
|