moved PyHandler to ObjC class
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1968E0AE14B8E8A90E194980 /* PyHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 1968EF7567E06D2A5BB3481A /* PyHandler.m */; };
|
||||
544FBD4521064AEB008A260C /* Python.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 544FBD4421064AEB008A260C /* Python.framework */; };
|
||||
544FBD4721064B2F008A260C /* getFeed.py in Resources */ = {isa = PBXBuildFile; fileRef = 544FBD4621064B2F008A260C /* getFeed.py */; };
|
||||
544FBD4921064DF0008A260C /* feedparser521.py in Resources */ = {isa = PBXBuildFile; fileRef = 544FBD4821064DF0008A260C /* feedparser521.py */; };
|
||||
@@ -17,10 +18,11 @@
|
||||
54ACC28C21061B3C0020715F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 54ACC28B21061B3C0020715F /* main.m */; };
|
||||
54ACC29521061E270020715F /* NewsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 54ACC29421061E270020715F /* NewsController.m */; };
|
||||
54ACC29821061FBA0020715F /* Preferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 54ACC29721061FBA0020715F /* Preferences.m */; };
|
||||
54ED7BDA2107CE5500AC8248 /* PyHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 54ED7BD92107CE5500AC8248 /* PyHandler.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1968E7919BAA36F042FCB717 /* PyHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyHandler.h; sourceTree = "<group>"; };
|
||||
1968EF7567E06D2A5BB3481A /* PyHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PyHandler.m; sourceTree = "<group>"; };
|
||||
544FBD4421064AEB008A260C /* Python.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Python.framework; path = System/Library/Frameworks/Python.framework; sourceTree = SDKROOT; };
|
||||
544FBD4621064B2F008A260C /* getFeed.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = getFeed.py; sourceTree = "<group>"; usesTabs = 0; };
|
||||
544FBD4821064DF0008A260C /* feedparser521.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = feedparser521.py; sourceTree = "<group>"; usesTabs = 0; };
|
||||
@@ -37,7 +39,6 @@
|
||||
54ACC29421061E270020715F /* NewsController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NewsController.m; sourceTree = "<group>"; };
|
||||
54ACC29621061FBA0020715F /* Preferences.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Preferences.h; sourceTree = "<group>"; };
|
||||
54ACC29721061FBA0020715F /* Preferences.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Preferences.m; sourceTree = "<group>"; };
|
||||
54ED7BD92107CE5500AC8248 /* PyHandler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PyHandler.cpp; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -60,6 +61,17 @@
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
549369F421091E6D001AF895 /* python */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1968E7919BAA36F042FCB717 /* PyHandler.h */,
|
||||
1968EF7567E06D2A5BB3481A /* PyHandler.m */,
|
||||
544FBD4621064B2F008A260C /* getFeed.py */,
|
||||
544FBD4821064DF0008A260C /* feedparser521.py */,
|
||||
);
|
||||
path = python;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
54ACC27321061B3B0020715F = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -80,9 +92,7 @@
|
||||
54ACC27E21061B3B0020715F /* baRSS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
54ED7BD92107CE5500AC8248 /* PyHandler.cpp */,
|
||||
544FBD4621064B2F008A260C /* getFeed.py */,
|
||||
544FBD4821064DF0008A260C /* feedparser521.py */,
|
||||
549369F421091E6D001AF895 /* python */,
|
||||
54ACC27F21061B3B0020715F /* AppDelegate.h */,
|
||||
54ACC28021061B3B0020715F /* AppDelegate.m */,
|
||||
54ACC29321061E270020715F /* NewsController.h */,
|
||||
@@ -179,9 +189,9 @@
|
||||
54ACC29521061E270020715F /* NewsController.m in Sources */,
|
||||
54ACC28421061B3B0020715F /* baRSS.xcdatamodeld in Sources */,
|
||||
54ACC28C21061B3C0020715F /* main.m in Sources */,
|
||||
54ED7BDA2107CE5500AC8248 /* PyHandler.cpp in Sources */,
|
||||
54ACC28121061B3B0020715F /* AppDelegate.m in Sources */,
|
||||
54ACC29821061FBA0020715F /* Preferences.m in Sources */,
|
||||
1968E0AE14B8E8A90E194980 /* PyHandler.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -313,6 +323,10 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_WARN_CXX0X_EXTENSIONS = YES;
|
||||
CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
|
||||
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
|
||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = baRSS/baRSS.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
@@ -322,6 +336,11 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)",
|
||||
);
|
||||
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
|
||||
GCC_WARN_SIGN_COMPARE = YES;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
|
||||
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
INFOPLIST_FILE = baRSS/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -340,6 +359,10 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_WARN_CXX0X_EXTENSIONS = YES;
|
||||
CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
|
||||
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;
|
||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = baRSS/baRSS.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
@@ -349,6 +372,11 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)",
|
||||
);
|
||||
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
|
||||
GCC_WARN_SIGN_COMPARE = YES;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
|
||||
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
||||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
INFOPLIST_FILE = baRSS/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
// SOFTWARE.
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "PyHandler.cpp"
|
||||
#import "PyHandler.h"
|
||||
|
||||
@interface AppDelegate ()
|
||||
@property (strong) NSStatusItem *statusItem;
|
||||
@@ -35,20 +35,21 @@
|
||||
}
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||
// Insert code here to initialize your application
|
||||
self.statusItem = [NSStatusBar.systemStatusBar statusItemWithLength:NSVariableStatusItemLength];
|
||||
self.statusItem.title = @"me";
|
||||
self.statusItem.menu = self.statusMenu;
|
||||
int a[] = {2017,8,9,13,9,59,0,0,0};
|
||||
printf("will init\n");
|
||||
pyhandler_init();
|
||||
[PyHandler prepare];
|
||||
printf("done\n");
|
||||
printf("%s", pyhandler_getWithDateArr([@"https://feeds.feedburner.com/simpledesktops" UTF8String], NULL, a));
|
||||
NSDictionary * obj = [PyHandler getFeed:@"https://feeds.feedburner.com/simpledesktops" withEtag:nil andModified:nil];
|
||||
NSLog(@"obj = %@", obj);
|
||||
[self quitClicked:nil];
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)aNotification {
|
||||
// Insert code here to tear down your application
|
||||
[PyHandler shutdown];
|
||||
}
|
||||
|
||||
#pragma mark - Core Data stack
|
||||
|
||||
29
baRSS/python/PyHandler.h
Normal file
29
baRSS/python/PyHandler.h
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
// Copyright (c) 2018 Oleg Geier
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
// of the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface PyHandler : NSObject
|
||||
+ (void)prepare; // must be called before getFeed
|
||||
+ (void)shutdown;
|
||||
+ (NSDictionary *)getFeed:(NSString *)url withEtag:(NSString *)etag andModified:(NSString *)modified;
|
||||
@end
|
||||
@@ -20,68 +20,96 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Python/Python.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#import "PyHandler.h"
|
||||
#import <Python/Python.h>
|
||||
|
||||
static PyObject *parseFeed;
|
||||
static PyObject *parseFeedModule;
|
||||
|
||||
PyObject* appBundlePath() {
|
||||
@implementation PyHandler
|
||||
|
||||
+ (PyObject*)appBundlePath {
|
||||
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
||||
CFURLRef appPath = CFBundleCopyResourcesDirectoryURL(mainBundle);
|
||||
CFURLRef absolutePath = CFURLCopyAbsoluteURL(appPath);
|
||||
CFStringRef path = CFURLCopyFileSystemPath(absolutePath, kCFURLPOSIXPathStyle);
|
||||
const char *resourcePath = CFStringGetCStringPtr(path, CFStringGetSystemEncoding());
|
||||
PyObject * pyStr = PyString_FromString(CFStringGetCStringPtr(path, CFStringGetSystemEncoding()));
|
||||
// const char *resourcePath = [[[NSBundle mainBundle] resourcePath] UTF8String];
|
||||
CFRelease(path);
|
||||
CFRelease(absolutePath);
|
||||
CFRelease(appPath);
|
||||
return PyString_FromString(resourcePath);
|
||||
return pyStr;
|
||||
}
|
||||
|
||||
void pyhandler_init() {
|
||||
+ (void)prepare {
|
||||
Py_Initialize();
|
||||
PyObject *sys = PyImport_Import(PyString_FromString("sys"));
|
||||
PyObject *sys_path_append = PyObject_GetAttrString(PyObject_GetAttrString(sys, "path"), "append");
|
||||
PyObject *resourcePath = PyTuple_New(1);
|
||||
PyTuple_SetItem(resourcePath, 0, appBundlePath());
|
||||
PyTuple_SetItem(resourcePath, 0, [self appBundlePath]);
|
||||
PyObject_CallObject(sys_path_append, resourcePath);
|
||||
|
||||
// import MyModule # this is in my project folder
|
||||
PyObject *myModule = PyImport_Import(PyString_FromString("getFeed"));
|
||||
parseFeed = PyObject_GetAttrString(myModule, "parse");
|
||||
parseFeedModule = PyObject_GetAttrString(myModule, "parse");
|
||||
}
|
||||
|
||||
void pyhandler_shutdown() {
|
||||
PyObject_Free(parseFeed);
|
||||
+ (void)shutdown {
|
||||
PyObject_Free(parseFeedModule);
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
char* pyhandler_run(PyObject *args) {
|
||||
if (parseFeed && PyCallable_Check(parseFeed)) {
|
||||
PyObject *result = PyObject_CallObject(parseFeed, args);
|
||||
+ (char*)run:(PyObject*)args {
|
||||
if (parseFeedModule && PyCallable_Check(parseFeedModule)) {
|
||||
PyObject *result = PyObject_CallObject(parseFeedModule, args);
|
||||
if (result != NULL && PyObject_TypeCheck(result, &PyString_Type))
|
||||
return PyString_AsString(result);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* pyhandler_getWithDateStr(const char * url, const char * etag, void * date) {
|
||||
return pyhandler_run(Py_BuildValue("(z z z)", url, etag, date));
|
||||
+ (char *)run:(const char *)url withEtag:(const char *)etag andDateString:(const char *)date {
|
||||
if (!Py_IsInitialized())
|
||||
return NULL;
|
||||
return [self run:Py_BuildValue("(z z z)", url, etag, date)];
|
||||
}
|
||||
|
||||
char* pyhandler_getWithDateArr(const char * url, const char * etag, int * d) {
|
||||
+ (char *)run:(const char *)url withEtag:(const char *)etag andDateArray:(int *)d {
|
||||
if (!Py_IsInitialized())
|
||||
return NULL;
|
||||
if (d == NULL || abs(d[8]) > 1) { // d[8] == tm_isdst (between -1 and 1). Array size must be 9
|
||||
return pyhandler_run(Py_BuildValue("(z z z)", url, etag, NULL));
|
||||
return [self run:Py_BuildValue("(z z z)", url, etag, NULL)];
|
||||
}
|
||||
return pyhandler_run(Py_BuildValue("(z z [iiiiiiiii])", url, etag,
|
||||
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8]));
|
||||
return [self run:Py_BuildValue("(z z [iiiiiiiii])", url, etag,
|
||||
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8])];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)getFeed:(NSString *)url withEtag:(NSString *)etag andModified:(NSString *)modified {
|
||||
const char* u = NULL;
|
||||
const char* e = NULL;
|
||||
const char* m = NULL;
|
||||
if (url && url.length > 0)
|
||||
u = [url UTF8String];
|
||||
if (etag && etag.length > 0)
|
||||
e = [etag UTF8String];
|
||||
if (modified && modified.length > 0)
|
||||
m = [modified UTF8String];
|
||||
|
||||
char *data = [self run:u withEtag:e andDateString:m];
|
||||
printf("JSON result:\n%s\n\n", data);
|
||||
if (data == NULL) return nil;
|
||||
|
||||
NSError *error = nil;
|
||||
id object = [NSJSONSerialization JSONObjectWithData:
|
||||
[[NSString stringWithUTF8String:data] dataUsingEncoding:NSUTF8StringEncoding]
|
||||
options:0 error:&error];
|
||||
|
||||
// @see https://docs.python.org/3/c-api/index.html
|
||||
if (error || !object || ![object isKindOfClass:[NSDictionary class]]) {
|
||||
return nil;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
// @see: https://docs.python.org/3/c-api/index.html
|
||||
/* PyObject *ObjcToPyObject(id object)
|
||||
{
|
||||
if (object == nil) {
|
||||
@@ -123,5 +151,6 @@ char* pyhandler_getWithDateArr(const char * url, const char * etag, int * d) {
|
||||
NSLog(@"ObjcToPyObject() could not convert Obj-C object to PyObject.");
|
||||
return NULL;
|
||||
}
|
||||
} */
|
||||
}*/
|
||||
|
||||
@end
|
||||
@@ -102,13 +102,7 @@ def prepareResult(obj):
|
||||
|
||||
|
||||
def parse(url, etag=None, modified=None):
|
||||
print "mod:", modified
|
||||
if isinstance(modified, list):
|
||||
modified = time.struct_time(modified)
|
||||
print url
|
||||
print etag
|
||||
print modified
|
||||
return '[{"name":"joe","title":"none"},{"value":24}]'
|
||||
# d = fp.parse(url, etag=etag, modified=modified)
|
||||
# return json.dumps(prepareResult(d), separators=(',', ':'))
|
||||
|
||||
d = fp.parse(url, etag=etag, modified=modified)
|
||||
return json.dumps(prepareResult(d), separators=(',', ':'))
|
||||
Reference in New Issue
Block a user