mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
New recipe for The COlumbus Dispatch by kwetal
This commit is contained in:
parent
c2bb98f37e
commit
f42faa0cb7
BIN
resources/images/news/columbusdispatch.png
Normal file
BIN
resources/images/news/columbusdispatch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 952 B |
80
resources/recipes/columbusdispatch.recipe
Normal file
80
resources/recipes/columbusdispatch.recipe
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class ColumbusDispatchRecipe(BasicNewsRecipe):
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__author__ = 'kwetal'
|
||||||
|
language = 'en'
|
||||||
|
version = 1
|
||||||
|
|
||||||
|
title = u'The Columbus Dispatch'
|
||||||
|
publisher = u'The Columbus Dispatch'
|
||||||
|
category = u'News, Newspaper'
|
||||||
|
description = u'Daily newspaper from central Ohio'
|
||||||
|
|
||||||
|
use_embedded_content = False
|
||||||
|
remove_empty_feeds = True
|
||||||
|
oldest_article = 1.2
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
|
||||||
|
no_stylesheets = True
|
||||||
|
remove_javascript = True
|
||||||
|
encoding = 'utf-8'
|
||||||
|
# Seems to work best, but YMMV
|
||||||
|
simultaneous_downloads = 2
|
||||||
|
|
||||||
|
# Feeds from http://www.dispatch.com/live/content/rss/index.html
|
||||||
|
feeds = []
|
||||||
|
feeds.append((u'News: Local and state news', u'http://www.dispatch.com/live/static/crt/2_rss_localnews.xml'))
|
||||||
|
feeds.append((u'News: National news', u'http://www.dispatch.com/live/static/crt/2_rss_nationalnews.xml'))
|
||||||
|
feeds.append((u'News: Editorials', u'http://www.dispatch.com/live/static/crt/2_rss_editorials.xml'))
|
||||||
|
feeds.append((u'News: Columnists', u'http://www.dispatch.com/live/static/crt/2_rss_columnists.xml'))
|
||||||
|
feeds.append((u'News: Health news', u'http://www.dispatch.com/live/static/crt/2_rss_health.xml'))
|
||||||
|
feeds.append((u'News: Science news', u'http://www.dispatch.com/live/static/crt/2_rss_science.xml'))
|
||||||
|
feeds.append((u'Sports: OSU football', u'http://www.dispatch.com/live/static/crt/2_rss_osufootball.xml'))
|
||||||
|
feeds.append((u'Sports: OSU men\'s basketball', u'http://www.dispatch.com/live/static/crt/2_rss_osumensbball.xml'))
|
||||||
|
feeds.append((u'Sports: OSU women\'s basketball', u'http://www.dispatch.com/live/static/crt/2_rss_osuwomensbball.xml'))
|
||||||
|
feeds.append((u'Sports: OSU sports', u'http://www.dispatch.com/live/static/crt/2_rss_osusports.xml'))
|
||||||
|
feeds.append((u'Sports: Blue Jackets', u'http://www.dispatch.com/live/static/crt/2_rss_bluejackets.xml'))
|
||||||
|
feeds.append((u'Sports: Crew', u'http://www.dispatch.com/live/static/crt/2_rss_crew.xml'))
|
||||||
|
feeds.append((u'Sports: Clippers', u'http://www.dispatch.com/live/static/crt/2_rss_clippers.xml'))
|
||||||
|
feeds.append((u'Sports: Indians', u'http://www.dispatch.com/live/static/crt/2_rss_indians.xml'))
|
||||||
|
feeds.append((u'Sports: Reds', u'http://www.dispatch.com/live/static/crt/2_rss_reds.xml'))
|
||||||
|
feeds.append((u'Sports: Golf', u'http://www.dispatch.com/live/static/crt/2_rss_golf.xml'))
|
||||||
|
feeds.append((u'Sports: Outdoors', u'http://www.dispatch.com/live/static/crt/2_rss_outdoors.xml'))
|
||||||
|
feeds.append((u'Sports: Cavs/NBA', u'http://www.dispatch.com/live/static/crt/2_rss_cavaliers.xml'))
|
||||||
|
feeds.append((u'Sports: High Schools', u'http://www.dispatch.com/live/static/crt/2_rss_highschools.xml'))
|
||||||
|
feeds.append((u'Sports: Browns', u'http://www.dispatch.com/live/static/crt/2_rss_browns.xml'))
|
||||||
|
feeds.append((u'Sports: Bengals', u'http://www.dispatch.com/live/static/crt/2_rss_bengals.xml'))
|
||||||
|
feeds.append((u'Sports: Auto Racing', u'http://www.dispatch.com/live/static/crt/2_rss_autoracing.xml'))
|
||||||
|
feeds.append((u'Business News', u'http://www.dispatch.com/live/static/crt/2_rss_business.xml'))
|
||||||
|
feeds.append((u'Features: Weekender', u'http://www.dispatch.com/live/static/crt/2_rss_weekender.xml'))
|
||||||
|
feeds.append((u'Features: Life and Arts', u'http://www.dispatch.com/live/static/crt/2_rss_lifearts.xml'))
|
||||||
|
feeds.append((u'Features: Food', u'http://www.dispatch.com/live/static/crt/2_rss_food.xml'))
|
||||||
|
feeds.append((u'Features: NOW! for kids', u'http://www.dispatch.com/live/static/crt/2_rss_now.xml'))
|
||||||
|
feeds.append((u'Features: Travel', u'http://www.dispatch.com/live/static/crt/2_rss_travel.xml'))
|
||||||
|
feeds.append((u'Features: Home and Garden', u'http://www.dispatch.com/live/static/crt/2_rss_homegarden.xml'))
|
||||||
|
feeds.append((u'Features: Faith and Values', u'http://www.dispatch.com/live/static/crt/2_rss_faithvalues.xml'))
|
||||||
|
#feeds.append((u'', u''))
|
||||||
|
|
||||||
|
keep_only_tags = []
|
||||||
|
keep_only_tags.append(dict(name = 'div', attrs = {'class': 'colhed'}))
|
||||||
|
keep_only_tags.append(dict(name = 'div', attrs = {'class': 'hed'}))
|
||||||
|
keep_only_tags.append(dict(name = 'div', attrs = {'class': 'subhed'}))
|
||||||
|
keep_only_tags.append(dict(name = 'div', attrs = {'class': 'date'}))
|
||||||
|
keep_only_tags.append(dict(name = 'div', attrs = {'class': 'byline'}))
|
||||||
|
keep_only_tags.append(dict(name = 'div', attrs = {'class': 'srcline'}))
|
||||||
|
keep_only_tags.append(dict(name = 'div', attrs = {'class': 'body'}))
|
||||||
|
|
||||||
|
remove_tags = []
|
||||||
|
remove_tags.append(dict(name = 'div', attrs = {'id': 'middle-story-ad-container'}))
|
||||||
|
|
||||||
|
extra_css = '''
|
||||||
|
body {font-family:verdana,arial,helvetica,geneva,sans-serif ;}
|
||||||
|
a {text-decoration: none; color: blue;}
|
||||||
|
div.colhed {font-weight: bold;}
|
||||||
|
div.hed {font-size: xx-large; font-weight: bold; margin-bottom: 0.2em;}
|
||||||
|
div.subhed {font-size: large;}
|
||||||
|
div.date {font-size: x-small; font-style: italic; color: #666666; margin-top: 0.4em; margin-bottom: 0.4em;}
|
||||||
|
div.byline, div.srcline {font-size: small; color: #696969;}
|
||||||
|
'''
|
||||||
|
|
@ -2,11 +2,7 @@ usbobserver.so : usbobserver.o
|
|||||||
gcc -arch i386 -arch ppc -bundle usbobserver.o -o usbobserver.so -framework Python -framework IOKit -framework CoreFoundation
|
gcc -arch i386 -arch ppc -bundle usbobserver.o -o usbobserver.so -framework Python -framework IOKit -framework CoreFoundation
|
||||||
|
|
||||||
usbobserver.o : usbobserver.c
|
usbobserver.o : usbobserver.c
|
||||||
gcc -arch i386 -arch ppc -dynamic -I/Library/Frameworks/Python.framework/Versions/2.5/include/python2.5 -c usbobserver.c -o usbobserver.o
|
gcc -arch i386 -arch ppc -dynamic -I/Library/Frameworks/Python.framework/Versions/Current/Headers -c usbobserver.c -o usbobserver.o
|
||||||
|
|
||||||
|
|
||||||
install : usbobserver.so
|
|
||||||
cp usbobserver.so /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/
|
|
||||||
|
|
||||||
clean :
|
clean :
|
||||||
rm -f *.o *.so
|
rm -f *.o *.so
|
||||||
|
@ -26,28 +26,34 @@
|
|||||||
|
|
||||||
#include <IOKit/usb/IOUSBLib.h>
|
#include <IOKit/usb/IOUSBLib.h>
|
||||||
#include <IOKit/IOCFPlugIn.h>
|
#include <IOKit/IOCFPlugIn.h>
|
||||||
|
#include <IOKit/IOKitLib.h>
|
||||||
#include <mach/mach.h>
|
#include <mach/mach.h>
|
||||||
|
|
||||||
|
CFStringRef USB_PROPS[3] = { CFSTR("USB Vendor Name"), CFSTR("USB Product Name"), CFSTR("USB Serial Number") };
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
get_iokit_string_property(io_service_t dev, int prop) {
|
||||||
|
CFTypeRef PropRef;
|
||||||
|
char buf[500];
|
||||||
|
|
||||||
|
PropRef = IORegistryEntryCreateCFProperty(dev, USB_PROPS[prop], kCFAllocatorDefault, 0);
|
||||||
|
if (PropRef) {
|
||||||
|
if(!CFStringGetCString(PropRef, buf, 500, kCFStringEncodingUTF8)) buf[0] = '\0';
|
||||||
|
} else buf[0] = '\0';
|
||||||
|
|
||||||
|
return PyUnicode_DecodeUTF8(buf, strlen(buf), "replace");
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
usbobserver_get_usb_devices(PyObject *self, PyObject *args) {
|
usbobserver_get_usb_devices(PyObject *self, PyObject *args) {
|
||||||
|
|
||||||
mach_port_t masterPort;
|
|
||||||
CFMutableDictionaryRef matchingDict;
|
CFMutableDictionaryRef matchingDict;
|
||||||
kern_return_t kr;
|
kern_return_t kr;
|
||||||
|
|
||||||
/* Create a master port for communication with IOKit */
|
|
||||||
kr = IOMasterPort(MACH_PORT_NULL, &masterPort);
|
|
||||||
|
|
||||||
if (kr || !masterPort) {
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Couldn't create master IOKit port");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set up matching dictionary for class IOUSBDevice and its subclasses
|
//Set up matching dictionary for class IOUSBDevice and its subclasses
|
||||||
matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
|
matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
|
||||||
if (!matchingDict) {
|
if (!matchingDict) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Couldn't create a USB matching dictionary");
|
PyErr_SetString(PyExc_RuntimeError, "Couldn't create a USB matching dictionary");
|
||||||
mach_port_deallocate(mach_task_self(), masterPort);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,12 +64,12 @@ usbobserver_get_usb_devices(PyObject *self, PyObject *args) {
|
|||||||
SInt32 score;
|
SInt32 score;
|
||||||
IOUSBDeviceInterface182 **dev = NULL;
|
IOUSBDeviceInterface182 **dev = NULL;
|
||||||
UInt16 vendor, product, bcd;
|
UInt16 vendor, product, bcd;
|
||||||
|
PyObject *manufacturer, *productn, *serial;
|
||||||
|
|
||||||
PyObject *devices, *device;
|
PyObject *devices, *device;
|
||||||
devices = PyList_New(0);
|
devices = PyList_New(0);
|
||||||
if (devices == NULL) {
|
if (devices == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
mach_port_deallocate(mach_task_self(), masterPort);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +91,15 @@ usbobserver_get_usb_devices(PyObject *self, PyObject *args) {
|
|||||||
kr = (*dev)->GetDeviceVendor(dev, &vendor);
|
kr = (*dev)->GetDeviceVendor(dev, &vendor);
|
||||||
kr = (*dev)->GetDeviceProduct(dev, &product);
|
kr = (*dev)->GetDeviceProduct(dev, &product);
|
||||||
kr = (*dev)->GetDeviceReleaseNumber(dev, &bcd);
|
kr = (*dev)->GetDeviceReleaseNumber(dev, &bcd);
|
||||||
device = Py_BuildValue("(iii)", vendor, product, bcd);
|
|
||||||
|
manufacturer = get_iokit_string_property(usbDevice, 0);
|
||||||
|
if (manufacturer == NULL) manufacturer = Py_None;
|
||||||
|
productn = get_iokit_string_property(usbDevice, 1);
|
||||||
|
if (productn == NULL) productn = Py_None;
|
||||||
|
serial = get_iokit_string_property(usbDevice, 2);
|
||||||
|
if (serial == NULL) serial = Py_None;
|
||||||
|
|
||||||
|
device = Py_BuildValue("(iiiOOO)", vendor, product, bcd, manufacturer, productn, serial);
|
||||||
if (device == NULL) {
|
if (device == NULL) {
|
||||||
IOObjectRelease(usbDevice);
|
IOObjectRelease(usbDevice);
|
||||||
(*plugInInterface)->Release(plugInInterface);
|
(*plugInInterface)->Release(plugInInterface);
|
||||||
@ -109,11 +123,7 @@ usbobserver_get_usb_devices(PyObject *self, PyObject *args) {
|
|||||||
Py_DECREF(device);
|
Py_DECREF(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return devices;
|
||||||
//Finished with master port
|
|
||||||
mach_port_deallocate(mach_task_self(), masterPort);
|
|
||||||
|
|
||||||
return Py_BuildValue("N", devices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef usbobserver_methods[] = {
|
static PyMethodDef usbobserver_methods[] = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user