Permalink
Browse files

Now done with integrating metaweb.py into app. First half of second s…

…egment.
  • Loading branch information...
1 parent dff3554 commit 79c87ffbac73f9b497582b6c9ef86f317764f2a0 @lethain committed Aug 23, 2008
View
5 MWController.py
@@ -6,7 +6,7 @@
# Copyright (c) 2008 Will Larson. All rights reserved.
#
-import objc
+import objc, metaweb
from Foundation import *
class MWController(NSObject):
@@ -17,4 +17,5 @@ class MWController(NSObject):
@objc.IBAction
def search_(self,sender):
search_value = self.textField.stringValue()
- NSLog(u"Search: %s" % search_value)
+ _results = metaweb.search(search_value)
+ NSLog(u"Search: %s" % _results)
View
4 MetaWindow.xcodeproj/project.pbxproj
@@ -14,6 +14,7 @@
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ BEA672E20E60965500FC6C91 /* metaweb.py in Resources */ = {isa = PBXBuildFile; fileRef = BEA672E10E60965500FC6C91 /* metaweb.py */; };
BEE9BD050E5F404A00CBCEC3 /* MWController.py in Resources */ = {isa = PBXBuildFile; fileRef = BEE9BD040E5F404A00CBCEC3 /* MWController.py */; };
/* End PBXBuildFile section */
@@ -31,6 +32,7 @@
77C8C1F80C07829500965286 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = "<group>"; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8D1107320486CEB800E47090 /* MetaWindow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MetaWindow.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ BEA672E10E60965500FC6C91 /* metaweb.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = metaweb.py; sourceTree = "<group>"; };
BEE9BD040E5F404A00CBCEC3 /* MWController.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = MWController.py; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -98,6 +100,7 @@
29B97315FDCFA39411CA2CEA /* Other Sources */ = {
isa = PBXGroup;
children = (
+ BEA672E10E60965500FC6C91 /* metaweb.py */,
32CA4F630368D1EE00C91783 /* MetaWindow_Prefix.pch */,
29B97316FDCFA39411CA2CEA /* main.m */,
77631A3E0C0748CF005415CB /* main.py */,
@@ -172,6 +175,7 @@
7790198F0C07548A00326F66 /* MetaWindowAppDelegate.py in Resources */,
77C8C1F90C07829500965286 /* MainMenu.xib in Resources */,
BEE9BD050E5F404A00CBCEC3 /* MWController.py in Resources */,
+ BEA672E20E60965500FC6C91 /* metaweb.py in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
78 MetaWindow.xcodeproj/will.mode1v3
@@ -275,13 +275,13 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
- <integer>7</integer>
- <integer>4</integer>
+ <integer>2</integer>
+ <integer>1</integer>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
- <string>{{0, 0}, {186, 445}}</string>
+ <string>{{0, 0}, {186, 553}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
@@ -293,14 +293,14 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
- <string>{{0, 0}, {203, 463}}</string>
+ <string>{{0, 0}, {203, 571}}</string>
<key>GroupTreeTableConfiguration</key>
<array>
<string>MainColumn</string>
<real>186</real>
</array>
<key>RubberWindowFrame</key>
- <string>499 223 788 504 0 0 1280 778 </string>
+ <string>479 166 791 612 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXSmartGroupTreeModule</string>
@@ -316,34 +316,37 @@
<key>PBXProjectModuleGUID</key>
<string>1CE0B20306471E060097A5F4</string>
<key>PBXProjectModuleLabel</key>
- <string>main.py</string>
+ <string>MWController.py</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1CE0B20406471E060097A5F4</string>
<key>PBXProjectModuleLabel</key>
- <string>main.py</string>
+ <string>MWController.py</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>BEE9BD2E0E5F74D200CBCEC3</string>
+ <string>BEA673030E60B55F00FC6C91</string>
<key>history</key>
<array>
<string>BEE9BD0E0E5F6FBC00CBCEC3</string>
- <string>BEE9BD0F0E5F6FBC00CBCEC3</string>
<string>BEE9BD290E5F74D200CBCEC3</string>
<string>BEE9BD2A0E5F74D200CBCEC3</string>
- <string>BEE9BD2B0E5F74D200CBCEC3</string>
+ <string>BEA672FE0E60B55F00FC6C91</string>
+ <string>BEA672FF0E60B55F00FC6C91</string>
+ <string>BEA673000E60B55F00FC6C91</string>
</array>
<key>prevStack</key>
<array>
<string>BEE9BD110E5F6FBC00CBCEC3</string>
<string>BEE9BD120E5F6FBC00CBCEC3</string>
<string>BEE9BD130E5F6FBC00CBCEC3</string>
<string>BEE9BD2C0E5F74D200CBCEC3</string>
- <string>BEE9BD2D0E5F74D200CBCEC3</string>
+ <string>BEA672F80E60ABD800FC6C91</string>
+ <string>BEA673010E60B55F00FC6C91</string>
+ <string>BEA673020E60B55F00FC6C91</string>
</array>
</dict>
<key>SplitCount</key>
@@ -355,14 +358,14 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
- <string>{{0, 0}, {580, 193}}</string>
+ <string>{{0, 0}, {583, 301}}</string>
<key>RubberWindowFrame</key>
- <string>499 223 788 504 0 0 1280 778 </string>
+ <string>479 166 791 612 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
- <string>193pt</string>
+ <string>301pt</string>
</dict>
<dict>
<key>BecomeActive</key>
@@ -377,9 +380,9 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
- <string>{{0, 198}, {580, 265}}</string>
+ <string>{{0, 306}, {583, 265}}</string>
<key>RubberWindowFrame</key>
- <string>499 223 788 504 0 0 1280 778 </string>
+ <string>479 166 791 612 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>XCDetailModule</string>
@@ -388,7 +391,7 @@
</dict>
</array>
<key>Proportion</key>
- <string>580pt</string>
+ <string>583pt</string>
</dict>
</array>
<key>Name</key>
@@ -403,9 +406,9 @@
</array>
<key>TableOfContents</key>
<array>
- <string>BEE9BCE50E5F354C00CBCEC3</string>
+ <string>BEA672BE0E60936700FC6C91</string>
<string>1CE0B1FE06471DED0097A5F4</string>
- <string>BEE9BCE60E5F354C00CBCEC3</string>
+ <string>BEA672BF0E60936700FC6C91</string>
<string>1CE0B20306471E060097A5F4</string>
<string>1CE0B20506471E060097A5F4</string>
</array>
@@ -539,12 +542,13 @@
<integer>5</integer>
<key>WindowOrderList</key>
<array>
- <string>1CD10A99069EF8BA00B06720</string>
- <string>BEE9BD150E5F6FBC00CBCEC3</string>
<string>1C78EAAD065D492600B07095</string>
+ <string>BEE9BD150E5F6FBC00CBCEC3</string>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <string>/Users/will/git/MetaWindow/MetaWindow.xcodeproj</string>
</array>
<key>WindowString</key>
- <string>499 223 788 504 0 0 1280 778 </string>
+ <string>479 166 791 612 0 0 1280 778 </string>
<key>WindowToolsV3</key>
<array>
<dict>
@@ -621,7 +625,7 @@
<key>TableOfContents</key>
<array>
<string>BEE9BD150E5F6FBC00CBCEC3</string>
- <string>BEE9BD160E5F6FBC00CBCEC3</string>
+ <string>BEA673040E60B55F00FC6C91</string>
<string>1CD0528F0623707200166675</string>
<string>XCMainBuildResultsModuleGUID</string>
</array>
@@ -663,8 +667,8 @@
<string>yes</string>
<key>sizes</key>
<array>
- <string>{{0, 0}, {316, 185}}</string>
- <string>{{316, 0}, {378, 185}}</string>
+ <string>{{0, 0}, {316, 194}}</string>
+ <string>{{316, 0}, {378, 194}}</string>
</array>
</dict>
<key>VerticalSplitView</key>
@@ -679,8 +683,8 @@
<string>yes</string>
<key>sizes</key>
<array>
- <string>{{0, 0}, {694, 185}}</string>
- <string>{{0, 185}, {694, 196}}</string>
+ <string>{{0, 0}, {694, 194}}</string>
+ <string>{{0, 194}, {694, 187}}</string>
</array>
</dict>
</dict>
@@ -713,7 +717,7 @@
<real>148</real>
</array>
<key>Frame</key>
- <string>{{316, 0}, {378, 185}}</string>
+ <string>{{316, 0}, {378, 194}}</string>
<key>RubberWindowFrame</key>
<string>520 282 694 422 0 0 1280 778 </string>
</dict>
@@ -741,13 +745,13 @@
<key>TableOfContents</key>
<array>
<string>1CD10A99069EF8BA00B06720</string>
- <string>BEE9BD170E5F6FBC00CBCEC3</string>
+ <string>BEA672C00E60936700FC6C91</string>
<string>1C162984064C10D400B95A72</string>
- <string>BEE9BD180E5F6FBC00CBCEC3</string>
- <string>BEE9BD190E5F6FBC00CBCEC3</string>
- <string>BEE9BD1A0E5F6FBC00CBCEC3</string>
- <string>BEE9BD1B0E5F6FBC00CBCEC3</string>
- <string>BEE9BD1C0E5F6FBC00CBCEC3</string>
+ <string>BEA672C10E60936700FC6C91</string>
+ <string>BEA672C20E60936700FC6C91</string>
+ <string>BEA672C30E60936700FC6C91</string>
+ <string>BEA672C40E60936700FC6C91</string>
+ <string>BEA672C50E60936700FC6C91</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.debugV3</string>
@@ -874,8 +878,6 @@
<key>Dock</key>
<array>
<dict>
- <key>BecomeActive</key>
- <true/>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
@@ -911,7 +913,7 @@
<key>TableOfContents</key>
<array>
<string>1C78EAAD065D492600B07095</string>
- <string>BEE9BD1D0E5F6FBC00CBCEC3</string>
+ <string>BEA673050E60B55F00FC6C91</string>
<string>1C78EAAC065D492600B07095</string>
</array>
<key>ToolbarConfiguration</key>
@@ -921,7 +923,7 @@
<key>WindowToolGUID</key>
<string>1C78EAAD065D492600B07095</string>
<key>WindowToolIsVisible</key>
- <true/>
+ <false/>
</dict>
<dict>
<key>Identifier</key>
View
200 MetaWindow.xcodeproj/will.pbxuser
@@ -25,9 +25,9 @@
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
- 341,
+ 344,
20,
- 48.16259765625,
+ 48,
43,
43,
20,
@@ -42,21 +42,35 @@
PBXFileDataSource_Target_ColumnID,
);
};
- PBXPerProjectTemplateStateSaveDate = 241120583;
- PBXWorkspaceStateSaveDate = 241120583;
+ PBXPerProjectTemplateStateSaveDate = 241210191;
+ PBXWorkspaceStateSaveDate = 241210191;
};
perUserProjectItems = {
- BEE9BD0E0E5F6FBC00CBCEC3 /* PBXTextBookmark */ = BEE9BD0E0E5F6FBC00CBCEC3 /* PBXTextBookmark */;
- BEE9BD0F0E5F6FBC00CBCEC3 /* PBXTextBookmark */ = BEE9BD0F0E5F6FBC00CBCEC3 /* PBXTextBookmark */;
- BEE9BD110E5F6FBC00CBCEC3 /* PBXTextBookmark */ = BEE9BD110E5F6FBC00CBCEC3 /* PBXTextBookmark */;
- BEE9BD120E5F6FBC00CBCEC3 /* PBXTextBookmark */ = BEE9BD120E5F6FBC00CBCEC3 /* PBXTextBookmark */;
- BEE9BD130E5F6FBC00CBCEC3 /* PBXTextBookmark */ = BEE9BD130E5F6FBC00CBCEC3 /* PBXTextBookmark */;
- BEE9BD290E5F74D200CBCEC3 /* PBXTextBookmark */ = BEE9BD290E5F74D200CBCEC3 /* PBXTextBookmark */;
- BEE9BD2A0E5F74D200CBCEC3 /* PBXTextBookmark */ = BEE9BD2A0E5F74D200CBCEC3 /* PBXTextBookmark */;
- BEE9BD2B0E5F74D200CBCEC3 /* PBXBookmark */ = BEE9BD2B0E5F74D200CBCEC3 /* PBXBookmark */;
- BEE9BD2C0E5F74D200CBCEC3 /* PBXTextBookmark */ = BEE9BD2C0E5F74D200CBCEC3 /* PBXTextBookmark */;
- BEE9BD2D0E5F74D200CBCEC3 /* PBXTextBookmark */ = BEE9BD2D0E5F74D200CBCEC3 /* PBXTextBookmark */;
- BEE9BD2E0E5F74D200CBCEC3 /* PBXTextBookmark */ = BEE9BD2E0E5F74D200CBCEC3 /* PBXTextBookmark */;
+ BEA672BC0E60936700FC6C91 /* PBXTextBookmark */ = BEA672BC0E60936700FC6C91 /* PBXTextBookmark */;
+ BEA672BD0E60936700FC6C91 /* PBXTextBookmark */ = BEA672BD0E60936700FC6C91 /* PBXTextBookmark */;
+ BEA672F50E60ABBF00FC6C91 /* PBXBookmark */ = BEA672F50E60ABBF00FC6C91 /* PBXBookmark */;
+ BEA672F60E60ABD800FC6C91 /* PBXTextBookmark */ = BEA672F60E60ABD800FC6C91 /* PBXTextBookmark */;
+ BEA672F70E60ABD800FC6C91 /* PBXTextBookmark */ = BEA672F70E60ABD800FC6C91 /* PBXTextBookmark */;
+ BEA672F80E60ABD800FC6C91 /* PBXTextBookmark */ = BEA672F80E60ABD800FC6C91 /* PBXTextBookmark */;
+ BEA672F90E60ABD800FC6C91 /* PBXTextBookmark */ = BEA672F90E60ABD800FC6C91 /* PBXTextBookmark */;
+ BEA672FC0E60ABD800FC6C91 /* PBXTextBookmark */ = BEA672FC0E60ABD800FC6C91 /* PBXTextBookmark */;
+ BEA672FE0E60B55F00FC6C91 /* PBXTextBookmark */ = BEA672FE0E60B55F00FC6C91 /* PBXTextBookmark */;
+ BEA672FF0E60B55F00FC6C91 /* PBXTextBookmark */ = BEA672FF0E60B55F00FC6C91 /* PBXTextBookmark */;
+ BEA673000E60B55F00FC6C91 /* PBXTextBookmark */ = BEA673000E60B55F00FC6C91 /* PBXTextBookmark */;
+ BEA673010E60B55F00FC6C91 /* PBXTextBookmark */ = BEA673010E60B55F00FC6C91 /* PBXTextBookmark */;
+ BEA673020E60B55F00FC6C91 /* PBXTextBookmark */ = BEA673020E60B55F00FC6C91 /* PBXTextBookmark */;
+ BEA673030E60B55F00FC6C91 /* PBXTextBookmark */ = BEA673030E60B55F00FC6C91 /* PBXTextBookmark */;
+ BEE9BD0E0E5F6FBC00CBCEC3 = BEE9BD0E0E5F6FBC00CBCEC3 /* PBXTextBookmark */;
+ BEE9BD0F0E5F6FBC00CBCEC3 = BEE9BD0F0E5F6FBC00CBCEC3 /* PBXTextBookmark */;
+ BEE9BD110E5F6FBC00CBCEC3 = BEE9BD110E5F6FBC00CBCEC3 /* PBXTextBookmark */;
+ BEE9BD120E5F6FBC00CBCEC3 = BEE9BD120E5F6FBC00CBCEC3 /* PBXTextBookmark */;
+ BEE9BD130E5F6FBC00CBCEC3 = BEE9BD130E5F6FBC00CBCEC3 /* PBXTextBookmark */;
+ BEE9BD290E5F74D200CBCEC3 = BEE9BD290E5F74D200CBCEC3 /* PBXTextBookmark */;
+ BEE9BD2A0E5F74D200CBCEC3 = BEE9BD2A0E5F74D200CBCEC3 /* PBXTextBookmark */;
+ BEE9BD2B0E5F74D200CBCEC3 = BEE9BD2B0E5F74D200CBCEC3 /* PBXBookmark */;
+ BEE9BD2C0E5F74D200CBCEC3 = BEE9BD2C0E5F74D200CBCEC3 /* PBXTextBookmark */;
+ BEE9BD2D0E5F74D200CBCEC3 = BEE9BD2D0E5F74D200CBCEC3 /* PBXTextBookmark */;
+ BEE9BD2E0E5F74D200CBCEC3 = BEE9BD2E0E5F74D200CBCEC3 /* PBXTextBookmark */;
};
sourceControlManager = BEE9BCE80E5F354C00CBCEC3 /* Source Control */;
userBuildSettings = {
@@ -80,9 +94,9 @@
};
77631A3E0C0748CF005415CB /* main.py */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {519, 322}}";
- sepNavSelRange = "{379, 1}";
- sepNavVisRange = "{162, 268}";
+ sepNavIntBoundsRect = "{{0, 0}, {519, 336}}";
+ sepNavSelRange = "{242, 151}";
+ sepNavVisRange = "{174, 271}";
sepNavWindowFrame = "{{620, 38}, {783, 738}}";
};
};
@@ -105,6 +119,148 @@
sepNavWindowFrame = "{{15, 35}, {783, 738}}";
};
};
+ BEA672BC0E60936700FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 77631A3E0C0748CF005415CB /* main.py */;
+ name = "main.py: 19";
+ rLen = 1;
+ rLoc = 394;
+ rType = 0;
+ vrLen = 268;
+ vrLoc = 162;
+ };
+ BEA672BD0E60936700FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 77631A3E0C0748CF005415CB /* main.py */;
+ name = "main.py: 19";
+ rLen = 1;
+ rLoc = 394;
+ rType = 0;
+ vrLen = 268;
+ vrLoc = 162;
+ };
+ BEA672E10E60965500FC6C91 /* metaweb.py */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {519, 6594}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 674}";
+ sepNavWindowFrame = "{{456, 13}, {783, 738}}";
+ };
+ };
+ BEA672F50E60ABBF00FC6C91 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = BEA672E10E60965500FC6C91 /* metaweb.py */;
+ };
+ BEA672F60E60ABD800FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 77631A3E0C0748CF005415CB /* main.py */;
+ name = "main.py: 19";
+ rLen = 1;
+ rLoc = 394;
+ rType = 0;
+ vrLen = 268;
+ vrLoc = 162;
+ };
+ BEA672F70E60ABD800FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = BEA672E10E60965500FC6C91 /* metaweb.py */;
+ name = "metaweb.py: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 674;
+ vrLoc = 0;
+ };
+ BEA672F80E60ABD800FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 77631A3E0C0748CF005415CB /* main.py */;
+ name = "main.py: 19";
+ rLen = 1;
+ rLoc = 394;
+ rType = 0;
+ vrLen = 268;
+ vrLoc = 162;
+ };
+ BEA672F90E60ABD800FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = BEA672E10E60965500FC6C91 /* metaweb.py */;
+ name = "metaweb.py: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 674;
+ vrLoc = 0;
+ };
+ BEA672FC0E60ABD800FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = BEA672E10E60965500FC6C91 /* metaweb.py */;
+ name = "metaweb.py: 376";
+ rLen = 0;
+ rLoc = 17209;
+ rType = 0;
+ vrLen = 1911;
+ vrLoc = 16249;
+ };
+ BEA672FE0E60B55F00FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = BEA672E10E60965500FC6C91 /* metaweb.py */;
+ name = "metaweb.py: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 674;
+ vrLoc = 0;
+ };
+ BEA672FF0E60B55F00FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 77631A3E0C0748CF005415CB /* main.py */;
+ name = "main.py: 16";
+ rLen = 151;
+ rLoc = 242;
+ rType = 0;
+ vrLen = 271;
+ vrLoc = 174;
+ };
+ BEA673000E60B55F00FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = BEE9BD040E5F404A00CBCEC3 /* MWController.py */;
+ name = "MWController.py: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 234;
+ vrLoc = 0;
+ };
+ BEA673010E60B55F00FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = BEA672E10E60965500FC6C91 /* metaweb.py */;
+ name = "metaweb.py: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 674;
+ vrLoc = 0;
+ };
+ BEA673020E60B55F00FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 77631A3E0C0748CF005415CB /* main.py */;
+ name = "main.py: 16";
+ rLen = 151;
+ rLoc = 242;
+ rType = 0;
+ vrLen = 271;
+ vrLoc = 174;
+ };
+ BEA673030E60B55F00FC6C91 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = BEE9BD040E5F404A00CBCEC3 /* MWController.py */;
+ name = "MWController.py: 17";
+ rLen = 188;
+ rLoc = 298;
+ rType = 0;
+ vrLen = 447;
+ vrLoc = 0;
+ };
BEE9BCD90E5F354700CBCEC3 /* MetaWindow */ = {
isa = PBXExecutable;
activeArgIndices = (
@@ -142,9 +298,9 @@
};
BEE9BD040E5F404A00CBCEC3 /* MWController.py */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {519, 350}}";
- sepNavSelRange = "{0, 0}";
- sepNavVisRange = "{0, 172}";
+ sepNavIntBoundsRect = "{{0, 0}, {522, 294}}";
+ sepNavSelRange = "{298, 188}";
+ sepNavVisRange = "{0, 447}";
sepNavWindowFrame = "{{475, -5}, {783, 738}}";
};
};
@@ -247,7 +403,7 @@
fRef = 77631A3E0C0748CF005415CB /* main.py */;
name = "main.py: 19";
rLen = 1;
- rLoc = 379;
+ rLoc = 394;
rType = 0;
vrLen = 268;
vrLoc = 162;
View
BIN build/MetaWindow.build/MetaWindow.pbxindex/pbxindex.header
Binary file not shown.
View
BIN build/MetaWindow.build/MetaWindow.pbxindex/strings.pbxstrings/control
Binary file not shown.
View
BIN build/MetaWindow.build/MetaWindow.pbxindex/symbols0.pbxsymbols
Binary file not shown.
View
1 main.py
@@ -14,6 +14,7 @@
from PyObjCTools import AppHelper
# import modules containing classes required to start application and load MainMenu.nib
+import metaweb
import MetaWindowAppDelegate
import MWController
View
469 metaweb.py
@@ -0,0 +1,469 @@
+#========================================================================
+# Copyright (c) 2007, Metaweb Technologies, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY METAWEB TECHNOLOGIES ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL METAWEB TECHNOLOGIES BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# ========================================================================
+#
+# This is the full "metaweb.py" module from the Metaweb API documentation
+#
+# In the documentation, each function is presented as a separate
+# example. This is the whole file.
+#
+# If you find any errors or have suggestions for improving this module,
+# send them to the Freebase developers mailing list: developers@freebase.com
+# You can subscribe to the mailing list at http://lists.freebase.com/
+#
+
+import httplib
+import urllib # URL encoding
+import urllib2 # Higher-level URL content fetching
+import simplejson # JSON serialization and parsing
+import cookielib # Cookie handling
+import os
+
+#
+# When experimenting, use the sandbox.freebase.com service.
+# Every Monday, sandbox.freebase.com is erased and it is updated
+# with a fresh copy of data from www.freebase.com. This makes
+# it an ideal place to experiment.
+#
+host = 'sandbox.freebase.com' # The Metaweb host
+readservice = '/api/service/mqlread' # Path to mqlread service
+loginservice = '/api/account/login' # Path to login service
+writeservice = '/api/service/mqlwrite' # Path to mqlwrite service
+uploadservice = '/api/service/upload' # Path to upload service
+searchservice = '/api/service/search' # Path to search service
+
+credentials = None # default credential from login()
+escape = False # default escape, set to 'html' for HTML escaping
+permission = None # default permission used when creating new objects
+debug = False # default debug setting
+
+# Install a CookieProcessor
+cookiefile = os.path.join(os.environ["HOME"], ".metaweb.cookies.txt")
+cookiejar = cookielib.LWPCookieJar()
+if os.path.isfile(cookiefile):
+ cookiejar.load(cookiefile)
+
+urllib2.install_opener(
+ urllib2.build_opener(
+ urllib2.HTTPCookieProcessor(cookiejar)))
+
+# If anything goes wrong when talking to a Metaweb service, we raise MQLError.
+class MQLError(Exception):
+ def __init__(self, value): # This is the exception constructor method
+ self.value = value
+ def __str__(self): # Convert error object to a string
+ return repr(self.value)
+
+# Submit the MQL query q and return the result as a Python object.
+# If authentication credentials are supplied, use them in a cookie.
+# Raises MQLError if the query was invalid. Raises urllib2.HTTPError if
+# mqlread returns an HTTP status code other than 200 (which should not happen).
+def read(q, credentials=credentials, escape=escape):
+ # Put the query in an envelope
+ envelope = {'query':q}
+
+ # Add escape if needed
+ if escape != 'html':
+ envelope['escape'] = False if not escape else escape
+
+ # Encode the result
+ encoded = urllib.urlencode({'query': simplejson.dumps(envelope)})
+
+ # Build the URL and create a Request object for it
+ url = 'http://%s%s' % (host, readservice)
+ req = urllib2.Request(url)
+
+ # The body of the POST request is encoded URL parameters
+ req.add_header('Content-type', 'application/x-www-form-urlencoded')
+
+ # Send our authentication credentials, if any, as a cookie.
+ # The need for mqlread authentication is a temporary restriction.
+ if credentials: req.add_header('Cookie', credentials)
+
+ # Use the encoded envelope as the value of the q parameter in the body
+ # of the request. Specifying a body automatically makes this a POST.
+ req.add_data(encoded)
+
+ # Now upen the URL and and parse its JSON content
+ f = urllib2.urlopen(req) # Open the URL
+ inner = simplejson.load(f) # Parse JSON response to an object
+
+ # If anything was wrong with the invocation, mqlread will return an HTTP
+ # error, and the code above with raise urllib2.HTTPError.
+ # If anything was wrong with the query, we won't get an HTTP error, but
+ # will get an error status code in the response envelope. In this case
+ # we raise our own MQLError exception.
+ if not inner['code'].startswith('/api/status/ok'):
+ if debug: print q
+ if debug: print inner
+ if debug: print f.info()['X-Metaweb-Cost']
+ if debug: print f.info()['X-Metaweb-TID']
+ error = inner['messages'][0]
+ raise MQLError('%s: %s' % (error['code'], error['message']))
+
+ # If there was no error, then just return the result from the envelope
+ return inner['result']
+
+# Submit the MQL query q and return the result as a Python object
+# This function behaves like read() above, but uses cursors so that
+# it works even for very large result sets. See also the cursor class below.
+def readall(q, credentials=credentials, escape=escape):
+ # This is the start of the mqlread URL.
+ # We just need to append the envelope to it
+ url = 'http://%s%s' % (host, readservice)
+
+ # The query and most of the envelope are constant. We just need to append
+ # the encoded cursor value and some closing braces to this prefix string
+ jsonq = simplejson.dumps(q)
+
+ # Add escape if needed
+ if escape != 'html':
+ jsonq += ',"escape":' + ('false' if not escape else escape)
+
+ cursor = 'true' # This is the initial value of the cursor
+ results = [] # We accumulate results in this array
+
+ # Loop until mqlread tells us there are no more results
+ while cursor:
+ # append the cursor and the closing braces to the envelope
+ envelope = urllib.urlencode({'query': '{"query":' + jsonq + ',"cursor":' + cursor + '}'})
+
+ # Begin an HTTP request for the URL
+ req = urllib2.Request(url)
+
+ # The body of the POST request is encoded URL parameters
+ req.add_header('Content-type', 'application/x-www-form-urlencoded')
+
+ # Send our authentication credentials, if any, as a cookie.
+ # The need for mqlread authentication is a temporary restriction.
+ if credentials:
+ req.add_header('Cookie', credentials)
+
+ # Use the encoded envelope as the value of the q parameter in the body
+ # of the request. Specifying a body automatically makes this a POST.
+ req.add_data(envelope)
+
+ # Read and parse the URL contents
+ f = urllib2.urlopen(req) # Open URL
+ inner = simplejson.load(f) # Parse JSON response
+
+ # Raise a MQLError if there were errors
+ if not inner['code'].startswith('/api/status/ok'):
+ if debug: print q
+ if debug: print inner
+ if debug: print f.info()['X-Metaweb-Cost']
+ if debug: print f.info()['X-Metaweb-TID']
+ error = inner['messages'][0]
+ raise MQLError('%s: %s' % (error['code'], error['message']))
+
+ # Append this batch of results to the main array of results.
+ results.extend(inner['result'])
+
+ # Finally, get the new value of the cursor for the next iteration
+ cursor = inner['cursor']
+ if cursor: # If it is not false, put it
+ cursor = '"' + cursor + '"' # in quotes as a JSON string
+
+ # Now that we're done with the loop, return the results array
+ return results
+
+# Submit multiple MQL queries and return the result as a Python array.
+# If authentication credentials are supplied, use them in a cookie.
+# Raises MQLError if the query was invalid. Raises urllib2.HTTPError if
+# mqlread returns an HTTP status code other than 200 (which should not happen).
+def readmulti(queries, credentials=credentials, escape=escape):
+ encoded = ""
+ for i in range(0, len(queries)):
+ # Put the query in an envelope
+ envelope = {'query':queries[i]}
+ # Add escape if needed
+ if escape != 'html':
+ envelope['escape'] = False if not escape else escape
+ if i > 0:
+ encoded += ","
+ encoded += '"q%d":%s' % (i, simplejson.dumps(envelope))
+
+ # URL encode the outer envelope
+ encoded = urllib.urlencode({'queries': "{" + encoded + "}"})
+
+ # Build the URL and create a Request object for it
+ url = 'http://%s%s' % (host, readservice)
+ req = urllib2.Request(url)
+
+ # The body of the POST request is encoded URL parameters
+ req.add_header('Content-type', 'application/x-www-form-urlencoded')
+
+ # Send our authentication credentials, if any, as a cookie.
+ # The need for mqlread authentication is a temporary restriction.
+ if credentials: req.add_header('Cookie', credentials)
+
+ # Use the encoded envelope as the value of the q parameter in the body
+ # of the request. Specifying a body automatically makes this a POST.
+ req.add_data(encoded)
+
+ # Now upen the URL and and parse its JSON content
+ f = urllib2.urlopen(req) # Open the URL
+ inner = simplejson.load(f) # Parse JSON response to an object
+
+ # If anything was wrong with the invocation, mqlread will return an HTTP
+ # error, and the code above with raise urllib2.HTTPError.
+ # If anything was wrong with the query, we won't get an HTTP error, but
+ # will get an error status code in the response envelope. In this case
+ # we raise our own MQLError exception.
+ if not inner['code'].startswith('/api/status/ok'):
+ if debug: print queries
+ if debug: print inner
+ if debug: print f.info()['X-Metaweb-Cost']
+ if debug: print f.info()['X-Metaweb-TID']
+ error = inner['messages'][0]
+ raise MQLError('%s: %s' % (error['code'], error['message']))
+
+ # extract the results
+ results = []
+ for i in range(0, len(queries)):
+ result = inner["q%d" % i]
+ if not result['code'].startswith('/api/status/ok'):
+ if debug: print queries[i]
+ if debug: print result
+ if debug: print f.info()['X-Metaweb-Cost']
+ if debug: print f.info()['X-Metaweb-TID']
+ error = result['messages'][0]
+ raise MQLError('%s: %s' % (error['code'], error['message']))
+ results.append(result['result'])
+
+ # If there was no error, then just return the result from the envelope
+ return results
+
+# Submit the specified username and password to the Metaweb login service.
+# Return opaque authentication credentials on success.
+# Raise MQLError on failure.
+def login(username, password):
+ # Establish a connection to the server and make a request.
+ # Note that we use the low-level httplib library instead of urllib2.
+ # This allows us to manage cookies explicitly.
+ conn = httplib.HTTPConnection(host)
+ conn.request('POST', # POST the request
+ loginservice, # The URL path /api/account/login
+ # The body of the request: encoded username/password
+ urllib.urlencode({'username':username, 'password':password}),
+ # This header specifies how the body of the post is encoded.
+ {'Content-type': 'application/x-www-form-urlencoded'})
+
+ # Get the response from the server
+ response = conn.getresponse()
+
+ if response.status == 200: # We get HTTP 200 OK even if login fails
+ # Parse response body and raise a MQLError if login failed
+ body = simplejson.loads(response.read())
+ if not body['code'].startswith('/api/status/ok'):
+ if debug: print inner
+ if debug: print f.info()['X-Metaweb-Cost']
+ if debug: print f.info()['X-Metaweb-TID']
+ error = body['messages'][0]
+ raise MQLError('%s: %s' % (error['code'], error['message']))
+
+ # Otherwise return cookies to serve as authentication credentials.
+ # The set-cookie header holds one or more cookie specifications,
+ # separated by commas. Each specification is a name, an equal
+ # sign, a value, and one or more trailing clauses that consist
+ # of a semicolon and some metadata. We don't care about the
+ # metadata. We just want to return a comma-separated list of
+ # name=value pairs.
+ cookies = response.getheader('set-cookie').split(',')
+ return ';'.join([c[0:c.index(';')] for c in cookies])
+ else: # This should never happen
+ raise MQLError('HTTP Error: %d %s' % (response.status,response.reason))
+
+
+# Submit the MQL write q and return the result as a Python object.
+# Authentication credentials are required, obtained from login()
+# Raises MQLError if the query was invalid. Raises urllib2.HTTPError if
+# mqlwrite returns an HTTP status code other than 200
+def write(query, credentials=credentials, escape=escape, permission=permission):
+ # We're requesting this URL
+ req = urllib2.Request('http://%s%s' % (host, writeservice))
+ # Send our authentication credentials as a cookie
+ if credentials:
+ req.add_header('Cookie', credentials)
+ # This custom header is required and guards against XSS attacks
+ req.add_header('X-Metaweb-Request', 'True')
+ # The body of the POST request is encoded URL parameters
+ req.add_header('Content-type', 'application/x-www-form-urlencoded')
+ # Wrap the query object in a query envelope
+ envelope = {'qname': {'query': query}}
+ # Add escape if needed
+ if escape != 'html':
+ envelope['qname']['escape'] = (False if not escape else escape)
+ # Add permissions if needed
+ if permission:
+ envelope['qname']['use_permission_of'] = permission
+ # JSON encode the envelope
+ encoded = simplejson.dumps(envelope)
+ # Use the encoded envelope as the value of the q parameter in the body
+ # of the request. Specifying a body automatically makes this a POST.
+ req.add_data(urllib.urlencode({'queries':encoded}))
+
+ # Now do the POST
+ f = urllib2.urlopen(req)
+ response = simplejson.load(f) # Parse HTTP response as JSON
+ inner = response['qname'] # Open outer envelope; get inner envelope
+
+ # If anything was wrong with the invocation, mqlwrite will return an HTTP
+ # error, and the code above with raise urllib2.HTTPError.
+ # If anything was wrong with the query, we will get an error status code
+ # in the response envelope.
+ # we raise our own MQLError exception.
+ if not inner['code'].startswith('/api/status/ok'):
+ if debug: print query
+ if debug: print inner
+ if debug: print f.info()['X-Metaweb-Cost']
+ if debug: print f.info()['X-Metaweb-TID']
+ error = inner['messages'][0]
+ raise MQLError('%s: %s' % (error['code'], error['message']))
+
+ # save cookie
+ cookiejar.save(cookiefile)
+
+ # If there was no error, then just return the result from the envelope
+ return inner['result']
+
+# Upload the specified content (and give it the specified type).
+# Return the guid of the /type/content object that represents it.
+# The returned guid can be used to retrieve the content with /api/trans/raw.
+def upload(content, type, credentials=credentials):
+ # This is the URL we POST content to
+ url = 'http://%s%s'%(host,uploadservice)
+ # Build the HTTP request
+ req = urllib2.Request(url, content) # URL and content to POST
+ req.add_header('Content-Type', type) # Content type header
+ if credentials:
+ req.add_header('Cookie', credentials) # Authentication header
+ req.add_header('X-Metaweb-Request', 'True') # Guard against XSS attacks
+ f = urllib2.urlopen(req) # POST the request
+ response = simplejson.load(f) # Parse the response
+ if not response['code'].startswith('/api/status/ok'):
+ if debug: print inner
+ if debug: print f.info()['X-Metaweb-Cost']
+ if debug: print f.info()['X-Metaweb-TID']
+ error = response['messages'][0]
+ raise MQLError('%s: %s' % (error['code'], error['message']))
+ return response['result']['id'] # Extract and return content id
+
+# Search for topics
+def search(query, type=None, start=0, limit=0):
+ args = {"query": query}
+ if type:
+ args["type"] = type
+ if start > 0:
+ args["start"] = start
+ if limit > 0:
+ args["limit"] = limit
+ url = 'http://%s%s?%s'%(host, searchservice, urllib.urlencode(args))
+ f = urllib2.urlopen(url)
+ response = simplejson.load(f) # Parse the response
+ if not response['code'].startswith('/api/status/ok'):
+ if debug: print query
+ if debug: print inner
+ if debug: print f.info()['X-Metaweb-Cost']
+ if debug: print f.info()['X-Metaweb-TID']
+ error = response['messages'][0]
+ raise MQLError('%s: %s' % (error['code'], error['message']))
+ return response['result']
+
+# Cursor for iterating over large data sets
+# For example:
+# query = {"name": None, "type":"/type/media_type"}
+# for row in metaweb.cursor([query]):
+# print row
+class cursor:
+ def __init__(self, query, credentials=credentials, escape=escape):
+ self.query = query
+ self.credentials = credentials
+ self.index = 0
+ self.results = []
+ self.cursor = 'true'
+ self.url = 'http://%s%s' % (host, readservice)
+ self.jsonq = simplejson.dumps(self.query)
+ if escape != 'html':
+ self.jsonq += ',"escape":' + ('false' if not escape else escape)
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ # return the next value
+ if self.index < len(self.results):
+ result = self.results[self.index]
+ self.index = self.index + 1
+ return result
+
+ # check if there is more
+ if not self.cursor:
+ raise StopIteration
+
+ # append the cursor and the closing braces to the envelope
+ envelope = urllib.urlencode({'query': '{"query":' + self.jsonq + ',"cursor":' + self.cursor + '}'})
+
+ # Begin an HTTP request for the URL
+ req = urllib2.Request(self.url)
+
+ # The body of the POST request is encoded URL parameters
+ req.add_header('Content-type', 'application/x-www-form-urlencoded')
+
+ # Send our authentication credentials, if any, as a cookie.
+ # The need for mqlread authentication is a temporary restriction.
+ if self.credentials: req.add_header('Cookie', self.credentials)
+
+ # Use the encoded envelope as the value of the q parameter in the body
+ # of the request. Specifying a body automatically makes this a POST.
+ req.add_data(envelope)
+
+ # Read and parse the URL contents
+ f = urllib2.urlopen(req) # Open URL
+ inner = simplejson.load(f) # Parse JSON response
+
+ # Raise a MQLError if there were errors
+ if not inner['code'].startswith('/api/status/ok'):
+ if debug: print self.query
+ if debug: print inner
+ if debug: print f.info()['X-Metaweb-Cost']
+ if debug: print f.info()['X-Metaweb-TID']
+ error = inner['messages'][0]
+ raise MQLError('%s: %s' % (error['code'], error['message']))
+
+ # Remember the next cursor
+ self.cursor = inner['cursor']
+ if self.cursor: # If it is not false, put it
+ self.cursor = '"' + self.cursor + '"' # in quotes as a JSON string
+
+ # Append this batch of results to the main array of results.
+ self.results = inner['result']
+ if len(self.results) == 0:
+ raise StopIteration
+
+ # Return the first result
+ self.index = 1
+ return self.results[0]

0 comments on commit 79c87ff

Please sign in to comment.