Get rid of ParseOptions()
That thing wasn't nice, and depended too much on the various use case. The new approach is to turn morss into a library and turn the use cases into some pre-implemented lib usagesmaster
parent
16713e6d2a
commit
b03d865b7b
14
README.md
14
README.md
|
@ -27,7 +27,7 @@ GPL3 code.
|
||||||
|
|
||||||
##Arguments
|
##Arguments
|
||||||
|
|
||||||
morss accepts some arguments, to lightly alter the output of morss. Arguments may need to have a value (usually a string or a number). In the different "Use cases" below is detailed how to pass those arguments to morss.
|
morss accepts some arguments, to lightly alter the output of morss. Arguments are all boolean. In the different "Use cases" below is detailed how to pass those arguments to morss.
|
||||||
|
|
||||||
The arguments are:
|
The arguments are:
|
||||||
|
|
||||||
|
@ -43,7 +43,6 @@ The arguments are:
|
||||||
- `cache`: only take articles from the cache (ie. don't grab new articles' content), so as to save time
|
- `cache`: only take articles from the cache (ie. don't grab new articles' content), so as to save time
|
||||||
- `debug`: to have some feedback from the script execution. Useful for debugging
|
- `debug`: to have some feedback from the script execution. Useful for debugging
|
||||||
- `theforce`: force download the rss feed
|
- `theforce`: force download the rss feed
|
||||||
- `al`: (takes an integer value, stands for *apparent limit*) only show `value` items in output (useful because browsers are actually super-slow to parse big JSON files)
|
|
||||||
- `silent`: don't output the final RSS (useless on its own, but can be nice when debugging)
|
- `silent`: don't output the final RSS (useless on its own, but can be nice when debugging)
|
||||||
- http server only
|
- http server only
|
||||||
- `html`: changes the http content-type to html, so that python cgi erros (written in html) are readable in a web browser
|
- `html`: changes the http content-type to html, so that python cgi erros (written in html) are readable in a web browser
|
||||||
|
@ -70,7 +69,7 @@ Morss can run its own HTTP server. The later should start when you run morss wit
|
||||||
|
|
||||||
####Passing arguments
|
####Passing arguments
|
||||||
|
|
||||||
Then visit: **`http://PATH/TO/MORSS/[morss.py/][:argwithoutvalue[:argwithvalue=value[...]]]/FEEDURL`**
|
Then visit: **`http://PATH/TO/MORSS/[morss.py/][:argwithoutvalue[...]]/FEEDURL`**
|
||||||
For example: `http://morss.example/:clip/https://twitter.com/pictuga`
|
For example: `http://morss.example/:clip/https://twitter.com/pictuga`
|
||||||
*(Brackets indicate optional text)*
|
*(Brackets indicate optional text)*
|
||||||
|
|
||||||
|
@ -80,7 +79,7 @@ Works like a charm with [Tiny Tiny RSS](http://tt-rss.org/redmine/projects/tt-rs
|
||||||
|
|
||||||
###As a CLI application
|
###As a CLI application
|
||||||
|
|
||||||
Run: **`[python2.7] morss.py [argwithoutvalue] [argwithvalue=value] [...] FEEDURL`**
|
Run: **`[python2.7] morss.py [argwithoutvalue] [...] FEEDURL`**
|
||||||
For example: `python2.7 morss.py debug http://feeds.bbci.co.uk/news/rss.xml`
|
For example: `python2.7 morss.py debug http://feeds.bbci.co.uk/news/rss.xml`
|
||||||
*(Brackets indicate optional text)*
|
*(Brackets indicate optional text)*
|
||||||
|
|
||||||
|
@ -88,20 +87,19 @@ For example: `python2.7 morss.py debug http://feeds.bbci.co.uk/news/rss.xml`
|
||||||
|
|
||||||
To use it, the newsreader [Liferea](http://lzone.de/liferea/) is required (unless other newsreaders provide the same kind of feature), since custom scripts can be run on top of the RSS feed, using its [output](http://lzone.de/liferea/scraping.htm) as an RSS feed.
|
To use it, the newsreader [Liferea](http://lzone.de/liferea/) is required (unless other newsreaders provide the same kind of feature), since custom scripts can be run on top of the RSS feed, using its [output](http://lzone.de/liferea/scraping.htm) as an RSS feed.
|
||||||
|
|
||||||
To use this script, you have to enable "(Unix) command" in liferea feed settings, and use the command: **`[python2.7] PATH/TO/MORSS/morss.py [argwithoutvalue] [argwithvalue=value] [...] FEEDURL`**
|
To use this script, you have to enable "(Unix) command" in liferea feed settings, and use the command: **`[python2.7] PATH/TO/MORSS/morss.py [argwithoutvalue] [...] FEEDURL`**
|
||||||
For example: `python2.7 PATH/TO/MORSS/morss.py http://feeds.bbci.co.uk/news/rss.xml`
|
For example: `python2.7 PATH/TO/MORSS/morss.py http://feeds.bbci.co.uk/news/rss.xml`
|
||||||
*(Brackets indicate optional text)*
|
*(Brackets indicate optional text)*
|
||||||
|
|
||||||
###As a python library
|
###As a python library
|
||||||
|
|
||||||
The code was not optimized to be used as a library. Therefore you can't really pass options to morss (see Arguments above), unless you rewrite the `ParseOptions` class.
|
The code was not optimized to be used as a library. However here is a quick draft of what your code should you like if you intend to use morss as a library.
|
||||||
However here is a quick draft of what your code should you like if you intend to use morss as a library.
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import morss
|
import morss
|
||||||
|
|
||||||
url = 'http://newspaper.example/feed.xml'
|
url = 'http://newspaper.example/feed.xml'
|
||||||
options = morss.ParseOptions() # there's no easy way to pass arguments by hand from python so far...
|
options = morss.Options(['force', 'quiet']) # arguments
|
||||||
cache_path = '/tmp/morss-cache' # cache folder, needs write permission
|
cache_path = '/tmp/morss-cache' # cache folder, needs write permission
|
||||||
url, cache = Init(url, cache_path, options)
|
url, cache = Init(url, cache_path, options)
|
||||||
|
|
||||||
|
|
|
@ -82,53 +82,18 @@ def countWord(txt):
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
class ParseOptions:
|
class Options:
|
||||||
def __init__(self, environ=False):
|
def __init__(self, options=None):
|
||||||
self.url = ''
|
self.options = options or []
|
||||||
self.options = {}
|
|
||||||
roptions = []
|
|
||||||
|
|
||||||
if environ:
|
|
||||||
if 'REQUEST_URI' in environ:
|
|
||||||
self.url = environ['REQUEST_URI'][1:]
|
|
||||||
else:
|
|
||||||
self.url = environ['PATH_INFO'][1:]
|
|
||||||
|
|
||||||
if self.url.startswith('/morss.py'):
|
|
||||||
self.url = self.url[10:]
|
|
||||||
elif self.url.startswith('morss.py'):
|
|
||||||
self.url = self.url[9:]
|
|
||||||
|
|
||||||
if self.url.startswith(':'):
|
|
||||||
roptions = self.url.split('/')[0].split(':')[1:]
|
|
||||||
self.url = self.url.split('/', 1)[1]
|
|
||||||
else:
|
|
||||||
if len(sys.argv) <= 1:
|
|
||||||
return
|
|
||||||
|
|
||||||
roptions = sys.argv[1:-1]
|
|
||||||
self.url = sys.argv[-1]
|
|
||||||
|
|
||||||
for option in roptions:
|
|
||||||
split = option.split('=', 1)
|
|
||||||
if len(split) > 1:
|
|
||||||
if split[0].lower() == 'true':
|
|
||||||
self.options[split[0]] = True
|
|
||||||
elif split[0].lower() == 'false':
|
|
||||||
self.options[split[0]] = False
|
|
||||||
else:
|
|
||||||
self.options[split[0]] = split[1]
|
|
||||||
else:
|
|
||||||
self.options[split[0]] = True
|
|
||||||
|
|
||||||
def __getattr__(self, key):
|
def __getattr__(self, key):
|
||||||
if key in self.options:
|
return key in self.options
|
||||||
return self.options[key]
|
|
||||||
else:
|
def __setitem__(self, key, value):
|
||||||
return False
|
self.options[key] = value
|
||||||
|
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
return self.options.__contains__(key)
|
return key in self.options
|
||||||
|
|
||||||
class Cache:
|
class Cache:
|
||||||
""" Light, error-prone caching system. """
|
""" Light, error-prone caching system. """
|
||||||
|
@ -682,8 +647,22 @@ def After(rss, options):
|
||||||
return rss.tostring(xml_declaration=True, encoding='UTF-8')
|
return rss.tostring(xml_declaration=True, encoding='UTF-8')
|
||||||
|
|
||||||
def cgi_app(environ, start_response):
|
def cgi_app(environ, start_response):
|
||||||
options = ParseOptions(environ)
|
# get options
|
||||||
url = options.url
|
if 'REQUEST_URI' in environ:
|
||||||
|
url = environ['REQUEST_URI'][1:]
|
||||||
|
else:
|
||||||
|
url = environ['PATH_INFO'][1:]
|
||||||
|
|
||||||
|
re.sub(r'^/?morss.py/', '', url)
|
||||||
|
|
||||||
|
if url.startswith(':'):
|
||||||
|
options = url.split('/')[0].split(':')[1:]
|
||||||
|
url = url.split('/', 1)[1]
|
||||||
|
else:
|
||||||
|
options = []
|
||||||
|
|
||||||
|
# init
|
||||||
|
options = Options(options)
|
||||||
headers = {}
|
headers = {}
|
||||||
|
|
||||||
global DEBUG
|
global DEBUG
|
||||||
|
@ -697,6 +676,7 @@ def cgi_app(environ, start_response):
|
||||||
log('etag good')
|
log('etag good')
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
# headers
|
||||||
headers['status'] = '200 OK'
|
headers['status'] = '200 OK'
|
||||||
headers['etag'] = '"%s"' % int(time.time())
|
headers['etag'] = '"%s"' % int(time.time())
|
||||||
|
|
||||||
|
@ -719,6 +699,7 @@ def cgi_app(environ, start_response):
|
||||||
start_response(headers['status'], headers.items())
|
start_response(headers['status'], headers.items())
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# get the work done
|
||||||
RSS = Fetch(url, cache, options)
|
RSS = Fetch(url, cache, options)
|
||||||
|
|
||||||
if headers['content-type'] == 'text/xml':
|
if headers['content-type'] == 'text/xml':
|
||||||
|
@ -779,8 +760,8 @@ def cgi_wrapper(environ, start_response):
|
||||||
return 'Unknown Error: %s' % e.message
|
return 'Unknown Error: %s' % e.message
|
||||||
|
|
||||||
def cli_app():
|
def cli_app():
|
||||||
options = ParseOptions()
|
options = Options(sys.argv[1:-1])
|
||||||
url = options.url
|
url = sys.argv[-1]
|
||||||
|
|
||||||
global DEBUG
|
global DEBUG
|
||||||
DEBUG = options.debug
|
DEBUG = options.debug
|
||||||
|
|
Loading…
Reference in New Issue