├── 09223K643-8.png ├── 1.gif ├── README.md ├── ed2kTools.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ ├── Mac.xcuserdatad │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ │ ├── ed2kTools.xcscheme │ │ └── xcschememanagement.plist │ └── phlx-mac1.xcuserdatad │ └── xcschemes │ ├── ed2kTools.xcscheme │ └── xcschememanagement.plist ├── ed2kTools ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ └── Main.storyboard ├── Classes │ ├── TFHpple.h │ ├── TFHpple.m │ ├── TFHppleElement.h │ ├── TFHppleElement.m │ ├── XPathQuery.h │ └── XPathQuery.m ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── 09223K643-8-1.png │ │ ├── 09223K643-8-2.png │ │ ├── 09223K643-8-3.png │ │ ├── 09223K643-8-4.png │ │ ├── 09223K643-8-5.png │ │ ├── 09223K643-8-6.png │ │ ├── 09223K643-8-7.png │ │ ├── 09223K643-8.png │ │ └── Contents.json ├── Info.plist ├── ViewController.h ├── ViewController.m ├── WindowController.h ├── WindowController.m ├── ed2kClass.h ├── ed2kClass.m ├── main.m └── weibo.png └── ed2kToolsTests ├── Info.plist └── ed2kToolsTests.m /09223K643-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youusername/ed2kTools/210e4dcab2ed2247c6db624e32af326e7ee52aae/09223K643-8.png -------------------------------------------------------------------------------- /1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youusername/ed2kTools/210e4dcab2ed2247c6db624e32af326e7ee52aae/1.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ed2kTools 2 | ##直接过滤网页内的电驴链接和磁力链接 MacOS OS X cocoa 苹果软件 3 | 4 | 5 | ![1.gif](https://github.com/youusername/ed2kTools/blob/master/1.gif) 6 | 7 | 8 | ##[软件下载地址(选择ed2kTools.app.zip)](https://github.com/youusername/ed2kTools/releases) 9 | 10 | ##ed2kTools有哪些功能? 11 | 12 | * 直接从目标网站页面内抓取电驴链接和磁力链接 13 | * 省事省力不必一个一个右键选择复制,现在起一键复制 14 | * 过滤不想看到的杂乱内容直取关键 15 | 16 | ##使用方法 17 | * 1.将目标网站粘贴进'通过目标网站'输入框 18 | * 2.点击GO 19 | * 3.左侧列表选择需要的内容进行勾选 20 | * 4.点击'全选'两个字可进行全选、取消全选 21 | * 5.点击'复制勾选链接'将选择好的内容链接复制进当前剪切板 22 | * 6.进入网盘或者下载工具的新建页面右键粘贴链接 23 | 24 | ##更新日志 25 | * 2016年11月25日 修改网络调用方法为异步,细节调整 26 | 27 | ##有问题反馈 28 | 在使用中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流 29 | 30 | * 邮件(214644496#QQ.com, 把#换成@) 31 | * QQ: 214644496 32 | * weibo: [@不娶名字不能看](http://weibo.com/u/2689574923) 33 | -------------------------------------------------------------------------------- /ed2kTools.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 043E48031BF09B4500D82DBF /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 043E48021BF09B4500D82DBF /* libxml2.tbd */; }; 11 | 043E48051BF09B5200D82DBF /* libxml2.2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 043E48041BF09B5100D82DBF /* libxml2.2.tbd */; }; 12 | 045C52201BCD040C00DBC0D2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 045C521F1BCD040C00DBC0D2 /* AppDelegate.m */; }; 13 | 045C52221BCD040C00DBC0D2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 045C52211BCD040C00DBC0D2 /* main.m */; }; 14 | 045C52251BCD040C00DBC0D2 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 045C52241BCD040C00DBC0D2 /* ViewController.m */; }; 15 | 045C52271BCD040C00DBC0D2 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 045C52261BCD040C00DBC0D2 /* Images.xcassets */; }; 16 | 045C522A1BCD040C00DBC0D2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 045C52281BCD040C00DBC0D2 /* Main.storyboard */; }; 17 | 045C52361BCD040C00DBC0D2 /* ed2kToolsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 045C52351BCD040C00DBC0D2 /* ed2kToolsTests.m */; }; 18 | 045C52461BCD04E100DBC0D2 /* TFHpple.m in Sources */ = {isa = PBXBuildFile; fileRef = 045C52411BCD04E100DBC0D2 /* TFHpple.m */; }; 19 | 045C52471BCD04E100DBC0D2 /* TFHppleElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 045C52431BCD04E100DBC0D2 /* TFHppleElement.m */; }; 20 | 045C52481BCD04E100DBC0D2 /* XPathQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 045C52451BCD04E100DBC0D2 /* XPathQuery.m */; }; 21 | 045C524A1BCD060A00DBC0D2 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 045C52491BCD060A00DBC0D2 /* libxml2.dylib */; }; 22 | 045C524C1BCD063900DBC0D2 /* libxml2.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 045C524B1BCD063900DBC0D2 /* libxml2.2.dylib */; }; 23 | 046509D11BD0BE5D006BE2DB /* ed2kClass.m in Sources */ = {isa = PBXBuildFile; fileRef = 046509D01BD0BE5D006BE2DB /* ed2kClass.m */; }; 24 | 046509D31BD0D00B006BE2DB /* weibo.png in Resources */ = {isa = PBXBuildFile; fileRef = 046509D21BD0D00B006BE2DB /* weibo.png */; }; 25 | 04D563131BCD130700CFD69D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04D563121BCD130700CFD69D /* Foundation.framework */; }; 26 | 04D563151BCD130E00CFD69D /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04D563141BCD130E00CFD69D /* AppKit.framework */; }; 27 | 04D563171BCD131500CFD69D /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04D563161BCD131500CFD69D /* CoreData.framework */; }; 28 | 04F793651BD8E4C400A68CFA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04F793641BD8E4C400A68CFA /* Cocoa.framework */; }; 29 | 04F793671BD8E4CD00A68CFA /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04F793661BD8E4CD00A68CFA /* CoreServices.framework */; }; 30 | 04F793691BD8E4D700A68CFA /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04F793681BD8E4D700A68CFA /* Security.framework */; }; 31 | 04F7936B1BD8E4DF00A68CFA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04F7936A1BD8E4DF00A68CFA /* SystemConfiguration.framework */; }; 32 | AA5792111DE808B600720919 /* WindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = AA5792101DE808B600720919 /* WindowController.m */; }; 33 | /* End PBXBuildFile section */ 34 | 35 | /* Begin PBXContainerItemProxy section */ 36 | 045C52301BCD040C00DBC0D2 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 045C52111BCD040C00DBC0D2 /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 045C52181BCD040C00DBC0D2; 41 | remoteInfo = ed2kTools; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 043E48021BF09B4500D82DBF /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = usr/lib/libxml2.tbd; sourceTree = SDKROOT; }; 47 | 043E48041BF09B5100D82DBF /* libxml2.2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.2.tbd; path = usr/lib/libxml2.2.tbd; sourceTree = SDKROOT; }; 48 | 045C52191BCD040C00DBC0D2 /* ed2kTools.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ed2kTools.app; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 045C521D1BCD040C00DBC0D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50 | 045C521E1BCD040C00DBC0D2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 51 | 045C521F1BCD040C00DBC0D2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 52 | 045C52211BCD040C00DBC0D2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 53 | 045C52231BCD040C00DBC0D2 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 54 | 045C52241BCD040C00DBC0D2 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 55 | 045C52261BCD040C00DBC0D2 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 56 | 045C52291BCD040C00DBC0D2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 57 | 045C522F1BCD040C00DBC0D2 /* ed2kToolsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ed2kToolsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 045C52341BCD040C00DBC0D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 59 | 045C52351BCD040C00DBC0D2 /* ed2kToolsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ed2kToolsTests.m; sourceTree = ""; }; 60 | 045C52401BCD04E100DBC0D2 /* TFHpple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TFHpple.h; sourceTree = ""; }; 61 | 045C52411BCD04E100DBC0D2 /* TFHpple.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TFHpple.m; sourceTree = ""; }; 62 | 045C52421BCD04E100DBC0D2 /* TFHppleElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TFHppleElement.h; sourceTree = ""; }; 63 | 045C52431BCD04E100DBC0D2 /* TFHppleElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TFHppleElement.m; sourceTree = ""; }; 64 | 045C52441BCD04E100DBC0D2 /* XPathQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPathQuery.h; sourceTree = ""; }; 65 | 045C52451BCD04E100DBC0D2 /* XPathQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XPathQuery.m; sourceTree = ""; }; 66 | 045C52491BCD060A00DBC0D2 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; }; 67 | 045C524B1BCD063900DBC0D2 /* libxml2.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.2.dylib; path = usr/lib/libxml2.2.dylib; sourceTree = SDKROOT; }; 68 | 046509CF1BD0BE5D006BE2DB /* ed2kClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ed2kClass.h; sourceTree = ""; }; 69 | 046509D01BD0BE5D006BE2DB /* ed2kClass.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ed2kClass.m; sourceTree = ""; }; 70 | 046509D21BD0D00B006BE2DB /* weibo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = weibo.png; sourceTree = ""; }; 71 | 04D563121BCD130700CFD69D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 72 | 04D563141BCD130E00CFD69D /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 73 | 04D563161BCD131500CFD69D /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 74 | 04F793641BD8E4C400A68CFA /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 75 | 04F793661BD8E4CD00A68CFA /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; 76 | 04F793681BD8E4D700A68CFA /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 77 | 04F7936A1BD8E4DF00A68CFA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; 78 | AA57920F1DE808B600720919 /* WindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowController.h; sourceTree = ""; }; 79 | AA5792101DE808B600720919 /* WindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WindowController.m; sourceTree = ""; }; 80 | /* End PBXFileReference section */ 81 | 82 | /* Begin PBXFrameworksBuildPhase section */ 83 | 045C52161BCD040C00DBC0D2 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | 043E48051BF09B5200D82DBF /* libxml2.2.tbd in Frameworks */, 88 | 043E48031BF09B4500D82DBF /* libxml2.tbd in Frameworks */, 89 | 04F7936B1BD8E4DF00A68CFA /* SystemConfiguration.framework in Frameworks */, 90 | 04F793691BD8E4D700A68CFA /* Security.framework in Frameworks */, 91 | 04F793671BD8E4CD00A68CFA /* CoreServices.framework in Frameworks */, 92 | 04F793651BD8E4C400A68CFA /* Cocoa.framework in Frameworks */, 93 | 04D563171BCD131500CFD69D /* CoreData.framework in Frameworks */, 94 | 04D563151BCD130E00CFD69D /* AppKit.framework in Frameworks */, 95 | 04D563131BCD130700CFD69D /* Foundation.framework in Frameworks */, 96 | 045C524C1BCD063900DBC0D2 /* libxml2.2.dylib in Frameworks */, 97 | 045C524A1BCD060A00DBC0D2 /* libxml2.dylib in Frameworks */, 98 | ); 99 | runOnlyForDeploymentPostprocessing = 0; 100 | }; 101 | 045C522C1BCD040C00DBC0D2 /* Frameworks */ = { 102 | isa = PBXFrameworksBuildPhase; 103 | buildActionMask = 2147483647; 104 | files = ( 105 | ); 106 | runOnlyForDeploymentPostprocessing = 0; 107 | }; 108 | /* End PBXFrameworksBuildPhase section */ 109 | 110 | /* Begin PBXGroup section */ 111 | 045C52101BCD040C00DBC0D2 = { 112 | isa = PBXGroup; 113 | children = ( 114 | 045C521B1BCD040C00DBC0D2 /* ed2kTools */, 115 | 045C52321BCD040C00DBC0D2 /* ed2kToolsTests */, 116 | 045C521A1BCD040C00DBC0D2 /* Products */, 117 | ); 118 | sourceTree = ""; 119 | }; 120 | 045C521A1BCD040C00DBC0D2 /* Products */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 045C52191BCD040C00DBC0D2 /* ed2kTools.app */, 124 | 045C522F1BCD040C00DBC0D2 /* ed2kToolsTests.xctest */, 125 | ); 126 | name = Products; 127 | sourceTree = ""; 128 | }; 129 | 045C521B1BCD040C00DBC0D2 /* ed2kTools */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 045C523F1BCD04E100DBC0D2 /* Classes */, 133 | 045C521E1BCD040C00DBC0D2 /* AppDelegate.h */, 134 | 045C521F1BCD040C00DBC0D2 /* AppDelegate.m */, 135 | AA57920F1DE808B600720919 /* WindowController.h */, 136 | AA5792101DE808B600720919 /* WindowController.m */, 137 | 046509D21BD0D00B006BE2DB /* weibo.png */, 138 | 045C52231BCD040C00DBC0D2 /* ViewController.h */, 139 | 045C52241BCD040C00DBC0D2 /* ViewController.m */, 140 | 046509CF1BD0BE5D006BE2DB /* ed2kClass.h */, 141 | 046509D01BD0BE5D006BE2DB /* ed2kClass.m */, 142 | 045C52261BCD040C00DBC0D2 /* Images.xcassets */, 143 | 045C52281BCD040C00DBC0D2 /* Main.storyboard */, 144 | 045C521C1BCD040C00DBC0D2 /* Supporting Files */, 145 | ); 146 | path = ed2kTools; 147 | sourceTree = ""; 148 | }; 149 | 045C521C1BCD040C00DBC0D2 /* Supporting Files */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 045C521D1BCD040C00DBC0D2 /* Info.plist */, 153 | 045C52211BCD040C00DBC0D2 /* main.m */, 154 | ); 155 | name = "Supporting Files"; 156 | sourceTree = ""; 157 | }; 158 | 045C52321BCD040C00DBC0D2 /* ed2kToolsTests */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 04F7936A1BD8E4DF00A68CFA /* SystemConfiguration.framework */, 162 | 04F793681BD8E4D700A68CFA /* Security.framework */, 163 | 04F793661BD8E4CD00A68CFA /* CoreServices.framework */, 164 | 04F793641BD8E4C400A68CFA /* Cocoa.framework */, 165 | 04D563161BCD131500CFD69D /* CoreData.framework */, 166 | 04D563141BCD130E00CFD69D /* AppKit.framework */, 167 | 04D563121BCD130700CFD69D /* Foundation.framework */, 168 | 045C524B1BCD063900DBC0D2 /* libxml2.2.dylib */, 169 | 045C52491BCD060A00DBC0D2 /* libxml2.dylib */, 170 | 043E48041BF09B5100D82DBF /* libxml2.2.tbd */, 171 | 043E48021BF09B4500D82DBF /* libxml2.tbd */, 172 | 045C52351BCD040C00DBC0D2 /* ed2kToolsTests.m */, 173 | 045C52331BCD040C00DBC0D2 /* Supporting Files */, 174 | ); 175 | path = ed2kToolsTests; 176 | sourceTree = ""; 177 | }; 178 | 045C52331BCD040C00DBC0D2 /* Supporting Files */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | 045C52341BCD040C00DBC0D2 /* Info.plist */, 182 | ); 183 | name = "Supporting Files"; 184 | sourceTree = ""; 185 | }; 186 | 045C523F1BCD04E100DBC0D2 /* Classes */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | 045C52401BCD04E100DBC0D2 /* TFHpple.h */, 190 | 045C52411BCD04E100DBC0D2 /* TFHpple.m */, 191 | 045C52421BCD04E100DBC0D2 /* TFHppleElement.h */, 192 | 045C52431BCD04E100DBC0D2 /* TFHppleElement.m */, 193 | 045C52441BCD04E100DBC0D2 /* XPathQuery.h */, 194 | 045C52451BCD04E100DBC0D2 /* XPathQuery.m */, 195 | ); 196 | path = Classes; 197 | sourceTree = ""; 198 | }; 199 | /* End PBXGroup section */ 200 | 201 | /* Begin PBXNativeTarget section */ 202 | 045C52181BCD040C00DBC0D2 /* ed2kTools */ = { 203 | isa = PBXNativeTarget; 204 | buildConfigurationList = 045C52391BCD040C00DBC0D2 /* Build configuration list for PBXNativeTarget "ed2kTools" */; 205 | buildPhases = ( 206 | 045C52151BCD040C00DBC0D2 /* Sources */, 207 | 045C52161BCD040C00DBC0D2 /* Frameworks */, 208 | 045C52171BCD040C00DBC0D2 /* Resources */, 209 | ); 210 | buildRules = ( 211 | ); 212 | dependencies = ( 213 | ); 214 | name = ed2kTools; 215 | productName = ed2kTools; 216 | productReference = 045C52191BCD040C00DBC0D2 /* ed2kTools.app */; 217 | productType = "com.apple.product-type.application"; 218 | }; 219 | 045C522E1BCD040C00DBC0D2 /* ed2kToolsTests */ = { 220 | isa = PBXNativeTarget; 221 | buildConfigurationList = 045C523C1BCD040C00DBC0D2 /* Build configuration list for PBXNativeTarget "ed2kToolsTests" */; 222 | buildPhases = ( 223 | 045C522B1BCD040C00DBC0D2 /* Sources */, 224 | 045C522C1BCD040C00DBC0D2 /* Frameworks */, 225 | 045C522D1BCD040C00DBC0D2 /* Resources */, 226 | ); 227 | buildRules = ( 228 | ); 229 | dependencies = ( 230 | 045C52311BCD040C00DBC0D2 /* PBXTargetDependency */, 231 | ); 232 | name = ed2kToolsTests; 233 | productName = ed2kToolsTests; 234 | productReference = 045C522F1BCD040C00DBC0D2 /* ed2kToolsTests.xctest */; 235 | productType = "com.apple.product-type.bundle.unit-test"; 236 | }; 237 | /* End PBXNativeTarget section */ 238 | 239 | /* Begin PBXProject section */ 240 | 045C52111BCD040C00DBC0D2 /* Project object */ = { 241 | isa = PBXProject; 242 | attributes = { 243 | LastUpgradeCheck = 0700; 244 | ORGANIZATIONNAME = Mac; 245 | TargetAttributes = { 246 | 045C52181BCD040C00DBC0D2 = { 247 | CreatedOnToolsVersion = 6.4; 248 | }; 249 | 045C522E1BCD040C00DBC0D2 = { 250 | CreatedOnToolsVersion = 6.4; 251 | TestTargetID = 045C52181BCD040C00DBC0D2; 252 | }; 253 | }; 254 | }; 255 | buildConfigurationList = 045C52141BCD040C00DBC0D2 /* Build configuration list for PBXProject "ed2kTools" */; 256 | compatibilityVersion = "Xcode 3.2"; 257 | developmentRegion = English; 258 | hasScannedForEncodings = 0; 259 | knownRegions = ( 260 | en, 261 | Base, 262 | ); 263 | mainGroup = 045C52101BCD040C00DBC0D2; 264 | productRefGroup = 045C521A1BCD040C00DBC0D2 /* Products */; 265 | projectDirPath = ""; 266 | projectRoot = ""; 267 | targets = ( 268 | 045C52181BCD040C00DBC0D2 /* ed2kTools */, 269 | 045C522E1BCD040C00DBC0D2 /* ed2kToolsTests */, 270 | ); 271 | }; 272 | /* End PBXProject section */ 273 | 274 | /* Begin PBXResourcesBuildPhase section */ 275 | 045C52171BCD040C00DBC0D2 /* Resources */ = { 276 | isa = PBXResourcesBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | 045C52271BCD040C00DBC0D2 /* Images.xcassets in Resources */, 280 | 046509D31BD0D00B006BE2DB /* weibo.png in Resources */, 281 | 045C522A1BCD040C00DBC0D2 /* Main.storyboard in Resources */, 282 | ); 283 | runOnlyForDeploymentPostprocessing = 0; 284 | }; 285 | 045C522D1BCD040C00DBC0D2 /* Resources */ = { 286 | isa = PBXResourcesBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | ); 290 | runOnlyForDeploymentPostprocessing = 0; 291 | }; 292 | /* End PBXResourcesBuildPhase section */ 293 | 294 | /* Begin PBXSourcesBuildPhase section */ 295 | 045C52151BCD040C00DBC0D2 /* Sources */ = { 296 | isa = PBXSourcesBuildPhase; 297 | buildActionMask = 2147483647; 298 | files = ( 299 | 045C52251BCD040C00DBC0D2 /* ViewController.m in Sources */, 300 | AA5792111DE808B600720919 /* WindowController.m in Sources */, 301 | 045C52221BCD040C00DBC0D2 /* main.m in Sources */, 302 | 045C52201BCD040C00DBC0D2 /* AppDelegate.m in Sources */, 303 | 045C52461BCD04E100DBC0D2 /* TFHpple.m in Sources */, 304 | 045C52481BCD04E100DBC0D2 /* XPathQuery.m in Sources */, 305 | 045C52471BCD04E100DBC0D2 /* TFHppleElement.m in Sources */, 306 | 046509D11BD0BE5D006BE2DB /* ed2kClass.m in Sources */, 307 | ); 308 | runOnlyForDeploymentPostprocessing = 0; 309 | }; 310 | 045C522B1BCD040C00DBC0D2 /* Sources */ = { 311 | isa = PBXSourcesBuildPhase; 312 | buildActionMask = 2147483647; 313 | files = ( 314 | 045C52361BCD040C00DBC0D2 /* ed2kToolsTests.m in Sources */, 315 | ); 316 | runOnlyForDeploymentPostprocessing = 0; 317 | }; 318 | /* End PBXSourcesBuildPhase section */ 319 | 320 | /* Begin PBXTargetDependency section */ 321 | 045C52311BCD040C00DBC0D2 /* PBXTargetDependency */ = { 322 | isa = PBXTargetDependency; 323 | target = 045C52181BCD040C00DBC0D2 /* ed2kTools */; 324 | targetProxy = 045C52301BCD040C00DBC0D2 /* PBXContainerItemProxy */; 325 | }; 326 | /* End PBXTargetDependency section */ 327 | 328 | /* Begin PBXVariantGroup section */ 329 | 045C52281BCD040C00DBC0D2 /* Main.storyboard */ = { 330 | isa = PBXVariantGroup; 331 | children = ( 332 | 045C52291BCD040C00DBC0D2 /* Base */, 333 | ); 334 | name = Main.storyboard; 335 | sourceTree = ""; 336 | }; 337 | /* End PBXVariantGroup section */ 338 | 339 | /* Begin XCBuildConfiguration section */ 340 | 045C52371BCD040C00DBC0D2 /* Debug */ = { 341 | isa = XCBuildConfiguration; 342 | buildSettings = { 343 | ALWAYS_SEARCH_USER_PATHS = YES; 344 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 345 | CLANG_CXX_LIBRARY = "libc++"; 346 | CLANG_ENABLE_MODULES = YES; 347 | CLANG_ENABLE_OBJC_ARC = YES; 348 | CLANG_WARN_BOOL_CONVERSION = YES; 349 | CLANG_WARN_CONSTANT_CONVERSION = YES; 350 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 351 | CLANG_WARN_EMPTY_BODY = YES; 352 | CLANG_WARN_ENUM_CONVERSION = YES; 353 | CLANG_WARN_INT_CONVERSION = YES; 354 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 355 | CLANG_WARN_UNREACHABLE_CODE = YES; 356 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 357 | CODE_SIGN_IDENTITY = "-"; 358 | COPY_PHASE_STRIP = NO; 359 | DEBUG_INFORMATION_FORMAT = dwarf; 360 | ENABLE_STRICT_OBJC_MSGSEND = YES; 361 | ENABLE_TESTABILITY = YES; 362 | GCC_C_LANGUAGE_STANDARD = gnu99; 363 | GCC_DYNAMIC_NO_PIC = NO; 364 | GCC_NO_COMMON_BLOCKS = YES; 365 | GCC_OPTIMIZATION_LEVEL = 0; 366 | GCC_PREPROCESSOR_DEFINITIONS = ( 367 | "DEBUG=1", 368 | "$(inherited)", 369 | ); 370 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 371 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 372 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 373 | GCC_WARN_UNDECLARED_SELECTOR = YES; 374 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 375 | GCC_WARN_UNUSED_FUNCTION = YES; 376 | GCC_WARN_UNUSED_VARIABLE = YES; 377 | HEADER_SEARCH_PATHS = ( 378 | "$(inherited)", 379 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 380 | "${SDKROOT}/usr/include/libxml2", 381 | ); 382 | MACOSX_DEPLOYMENT_TARGET = 10.8; 383 | MTL_ENABLE_DEBUG_INFO = YES; 384 | ONLY_ACTIVE_ARCH = YES; 385 | SDKROOT = macosx; 386 | }; 387 | name = Debug; 388 | }; 389 | 045C52381BCD040C00DBC0D2 /* Release */ = { 390 | isa = XCBuildConfiguration; 391 | buildSettings = { 392 | ALWAYS_SEARCH_USER_PATHS = YES; 393 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 394 | CLANG_CXX_LIBRARY = "libc++"; 395 | CLANG_ENABLE_MODULES = YES; 396 | CLANG_ENABLE_OBJC_ARC = YES; 397 | CLANG_WARN_BOOL_CONVERSION = YES; 398 | CLANG_WARN_CONSTANT_CONVERSION = YES; 399 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 400 | CLANG_WARN_EMPTY_BODY = YES; 401 | CLANG_WARN_ENUM_CONVERSION = YES; 402 | CLANG_WARN_INT_CONVERSION = YES; 403 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 404 | CLANG_WARN_UNREACHABLE_CODE = YES; 405 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 406 | CODE_SIGN_IDENTITY = "-"; 407 | COPY_PHASE_STRIP = NO; 408 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 409 | ENABLE_NS_ASSERTIONS = NO; 410 | ENABLE_STRICT_OBJC_MSGSEND = YES; 411 | GCC_C_LANGUAGE_STANDARD = gnu99; 412 | GCC_NO_COMMON_BLOCKS = YES; 413 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 414 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 415 | GCC_WARN_UNDECLARED_SELECTOR = YES; 416 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 417 | GCC_WARN_UNUSED_FUNCTION = YES; 418 | GCC_WARN_UNUSED_VARIABLE = YES; 419 | HEADER_SEARCH_PATHS = ( 420 | "$(inherited)", 421 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 422 | "${SDKROOT}/usr/include/libxml2", 423 | ); 424 | MACOSX_DEPLOYMENT_TARGET = 10.8; 425 | MTL_ENABLE_DEBUG_INFO = NO; 426 | SDKROOT = macosx; 427 | }; 428 | name = Release; 429 | }; 430 | 045C523A1BCD040C00DBC0D2 /* Debug */ = { 431 | isa = XCBuildConfiguration; 432 | buildSettings = { 433 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 434 | COMBINE_HIDPI_IMAGES = YES; 435 | INFOPLIST_FILE = ed2kTools/Info.plist; 436 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 437 | MACOSX_DEPLOYMENT_TARGET = 10.8; 438 | PRODUCT_BUNDLE_IDENTIFIER = "JingZhang.$(PRODUCT_NAME:rfc1034identifier)"; 439 | PRODUCT_NAME = "$(TARGET_NAME)"; 440 | }; 441 | name = Debug; 442 | }; 443 | 045C523B1BCD040C00DBC0D2 /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | buildSettings = { 446 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 447 | COMBINE_HIDPI_IMAGES = YES; 448 | INFOPLIST_FILE = ed2kTools/Info.plist; 449 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 450 | MACOSX_DEPLOYMENT_TARGET = 10.8; 451 | PRODUCT_BUNDLE_IDENTIFIER = "JingZhang.$(PRODUCT_NAME:rfc1034identifier)"; 452 | PRODUCT_NAME = "$(TARGET_NAME)"; 453 | }; 454 | name = Release; 455 | }; 456 | 045C523D1BCD040C00DBC0D2 /* Debug */ = { 457 | isa = XCBuildConfiguration; 458 | buildSettings = { 459 | BUNDLE_LOADER = "$(TEST_HOST)"; 460 | COMBINE_HIDPI_IMAGES = YES; 461 | FRAMEWORK_SEARCH_PATHS = ( 462 | "$(DEVELOPER_FRAMEWORKS_DIR)", 463 | "$(inherited)", 464 | ); 465 | GCC_PREPROCESSOR_DEFINITIONS = ( 466 | "DEBUG=1", 467 | "$(inherited)", 468 | ); 469 | INFOPLIST_FILE = ed2kToolsTests/Info.plist; 470 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 471 | PRODUCT_BUNDLE_IDENTIFIER = "JingZhang.$(PRODUCT_NAME:rfc1034identifier)"; 472 | PRODUCT_NAME = "$(TARGET_NAME)"; 473 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ed2kTools.app/Contents/MacOS/ed2kTools"; 474 | }; 475 | name = Debug; 476 | }; 477 | 045C523E1BCD040C00DBC0D2 /* Release */ = { 478 | isa = XCBuildConfiguration; 479 | buildSettings = { 480 | BUNDLE_LOADER = "$(TEST_HOST)"; 481 | COMBINE_HIDPI_IMAGES = YES; 482 | FRAMEWORK_SEARCH_PATHS = ( 483 | "$(DEVELOPER_FRAMEWORKS_DIR)", 484 | "$(inherited)", 485 | ); 486 | INFOPLIST_FILE = ed2kToolsTests/Info.plist; 487 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 488 | PRODUCT_BUNDLE_IDENTIFIER = "JingZhang.$(PRODUCT_NAME:rfc1034identifier)"; 489 | PRODUCT_NAME = "$(TARGET_NAME)"; 490 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ed2kTools.app/Contents/MacOS/ed2kTools"; 491 | }; 492 | name = Release; 493 | }; 494 | /* End XCBuildConfiguration section */ 495 | 496 | /* Begin XCConfigurationList section */ 497 | 045C52141BCD040C00DBC0D2 /* Build configuration list for PBXProject "ed2kTools" */ = { 498 | isa = XCConfigurationList; 499 | buildConfigurations = ( 500 | 045C52371BCD040C00DBC0D2 /* Debug */, 501 | 045C52381BCD040C00DBC0D2 /* Release */, 502 | ); 503 | defaultConfigurationIsVisible = 0; 504 | defaultConfigurationName = Release; 505 | }; 506 | 045C52391BCD040C00DBC0D2 /* Build configuration list for PBXNativeTarget "ed2kTools" */ = { 507 | isa = XCConfigurationList; 508 | buildConfigurations = ( 509 | 045C523A1BCD040C00DBC0D2 /* Debug */, 510 | 045C523B1BCD040C00DBC0D2 /* Release */, 511 | ); 512 | defaultConfigurationIsVisible = 0; 513 | defaultConfigurationName = Release; 514 | }; 515 | 045C523C1BCD040C00DBC0D2 /* Build configuration list for PBXNativeTarget "ed2kToolsTests" */ = { 516 | isa = XCConfigurationList; 517 | buildConfigurations = ( 518 | 045C523D1BCD040C00DBC0D2 /* Debug */, 519 | 045C523E1BCD040C00DBC0D2 /* Release */, 520 | ); 521 | defaultConfigurationIsVisible = 0; 522 | defaultConfigurationName = Release; 523 | }; 524 | /* End XCConfigurationList section */ 525 | }; 526 | rootObject = 045C52111BCD040C00DBC0D2 /* Project object */; 527 | } 528 | -------------------------------------------------------------------------------- /ed2kTools.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ed2kTools.xcodeproj/xcuserdata/Mac.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 38 | 39 | 40 | 42 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /ed2kTools.xcodeproj/xcuserdata/Mac.xcuserdatad/xcschemes/ed2kTools.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 93 | 94 | 95 | 96 | 102 | 104 | 110 | 111 | 112 | 113 | 115 | 116 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /ed2kTools.xcodeproj/xcuserdata/Mac.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ed2kTools.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 045C52181BCD040C00DBC0D2 16 | 17 | primary 18 | 19 | 20 | 045C522E1BCD040C00DBC0D2 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ed2kTools.xcodeproj/xcuserdata/phlx-mac1.xcuserdatad/xcschemes/ed2kTools.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /ed2kTools.xcodeproj/xcuserdata/phlx-mac1.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ed2kTools.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 045C52181BCD040C00DBC0D2 16 | 17 | primary 18 | 19 | 20 | 045C522E1BCD040C00DBC0D2 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ed2kTools/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ed2kTools 4 | // 5 | // Created by Mac on 15/10/13. 6 | // Copyright (c) 2015年 Mac. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | @property (nonatomic,strong) NSWindow*RootWindow; 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ed2kTools/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ed2kTools 4 | // 5 | // Created by Mac on 15/10/13. 6 | // Copyright (c) 2015年 Mac. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | 12 | @implementation AppDelegate 13 | 14 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 15 | // Insert code here to initialize your application 16 | } 17 | 18 | - (void)applicationWillTerminate:(NSNotification *)aNotification { 19 | // Insert code here to tear down your application 20 | } 21 | - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication 22 | hasVisibleWindows:(BOOL)flag{ 23 | // if (!flag){//是否有可见窗口 24 | //主窗口显示 25 | // [NSApp activateIgnoringOtherApps:NO]; 26 | [self.RootWindow makeKeyAndOrderFront:self]; 27 | 28 | 29 | // } 30 | 31 | 32 | return YES; 33 | } 34 | @end 35 | -------------------------------------------------------------------------------- /ed2kTools/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | Default 512 | 513 | 514 | 515 | 516 | 517 | 518 | Left to Right 519 | 520 | 521 | 522 | 523 | 524 | 525 | Right to Left 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | Default 537 | 538 | 539 | 540 | 541 | 542 | 543 | Left to Right 544 | 545 | 546 | 547 | 548 | 549 | 550 | Right to Left 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 790 | 794 | 795 | 796 | 797 | 798 | 799 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 838 | 852 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | -------------------------------------------------------------------------------- /ed2kTools/Classes/TFHpple.h: -------------------------------------------------------------------------------- 1 | // 2 | // TFHpple.h 3 | // Hpple 4 | // 5 | // Created by Geoffrey Grosenbach on 1/31/09. 6 | // 7 | // Copyright (c) 2009 Topfunky Corporation, http://topfunky.com 8 | // 9 | // MIT LICENSE 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining 12 | // a copy of this software and associated documentation files (the 13 | // "Software"), to deal in the Software without restriction, including 14 | // without limitation the rights to use, copy, modify, merge, publish, 15 | // distribute, sublicense, and/or sell copies of the Software, and to 16 | // permit persons to whom the Software is furnished to do so, subject to 17 | // the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be 20 | // included in all copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | 30 | 31 | #import 32 | 33 | #import "TFHppleElement.h" 34 | 35 | @interface TFHpple : NSObject 36 | 37 | - (id) initWithData:(NSData *)theData encoding:(NSString *)encoding isXML:(BOOL)isDataXML; 38 | - (id) initWithData:(NSData *)theData isXML:(BOOL)isDataXML; 39 | - (id) initWithXMLData:(NSData *)theData encoding:(NSString *)encoding; 40 | - (id) initWithXMLData:(NSData *)theData; 41 | - (id) initWithHTMLData:(NSData *)theData encoding:(NSString *)encoding; 42 | - (id) initWithHTMLData:(NSData *)theData; 43 | 44 | + (TFHpple *) hppleWithData:(NSData *)theData encoding:(NSString *)encoding isXML:(BOOL)isDataXML; 45 | + (TFHpple *) hppleWithData:(NSData *)theData isXML:(BOOL)isDataXML; 46 | + (TFHpple *) hppleWithXMLData:(NSData *)theData encoding:(NSString *)encoding; 47 | + (TFHpple *) hppleWithXMLData:(NSData *)theData; 48 | + (TFHpple *) hppleWithHTMLData:(NSData *)theData encoding:(NSString *)encoding; 49 | + (TFHpple *) hppleWithHTMLData:(NSData *)theData; 50 | 51 | - (NSArray *) searchWithXPathQuery:(NSString *)xPathOrCSS; 52 | - (TFHppleElement *) peekAtSearchWithXPathQuery:(NSString *)xPathOrCSS; 53 | 54 | @property (nonatomic, readonly) NSData * data; 55 | @property (nonatomic, readonly) NSString * encoding; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /ed2kTools/Classes/TFHpple.m: -------------------------------------------------------------------------------- 1 | // 2 | // TFHpple.m 3 | // Hpple 4 | // 5 | // Created by Geoffrey Grosenbach on 1/31/09. 6 | // 7 | // Copyright (c) 2009 Topfunky Corporation, http://topfunky.com 8 | // 9 | // MIT LICENSE 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining 12 | // a copy of this software and associated documentation files (the 13 | // "Software"), to deal in the Software without restriction, including 14 | // without limitation the rights to use, copy, modify, merge, publish, 15 | // distribute, sublicense, and/or sell copies of the Software, and to 16 | // permit persons to whom the Software is furnished to do so, subject to 17 | // the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be 20 | // included in all copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | 30 | #import "TFHpple.h" 31 | #import "XPathQuery.h" 32 | 33 | @interface TFHpple () 34 | { 35 | NSData * data; 36 | NSString * encoding; 37 | BOOL isXML; 38 | } 39 | 40 | @end 41 | 42 | 43 | @implementation TFHpple 44 | 45 | @synthesize data; 46 | @synthesize encoding; 47 | 48 | 49 | - (id) initWithData:(NSData *)theData encoding:(NSString *)theEncoding isXML:(BOOL)isDataXML 50 | { 51 | if (!(self = [super init])) { 52 | return nil; 53 | } 54 | 55 | data = theData; 56 | encoding = theEncoding; 57 | isXML = isDataXML; 58 | 59 | return self; 60 | } 61 | 62 | - (id) initWithData:(NSData *)theData isXML:(BOOL)isDataXML 63 | { 64 | return [self initWithData:theData encoding:nil isXML:isDataXML]; 65 | } 66 | 67 | - (id) initWithXMLData:(NSData *)theData encoding:(NSString *)theEncoding 68 | { 69 | return [self initWithData:theData encoding:theEncoding isXML:YES]; 70 | } 71 | 72 | - (id) initWithXMLData:(NSData *)theData 73 | { 74 | return [self initWithData:theData encoding:nil isXML:YES]; 75 | } 76 | 77 | - (id) initWithHTMLData:(NSData *)theData encoding:(NSString *)theEncoding 78 | { 79 | return [self initWithData:theData encoding:theEncoding isXML:NO]; 80 | } 81 | 82 | - (id) initWithHTMLData:(NSData *)theData 83 | { 84 | return [self initWithData:theData encoding:nil isXML:NO]; 85 | } 86 | 87 | + (TFHpple *) hppleWithData:(NSData *)theData encoding:(NSString *)theEncoding isXML:(BOOL)isDataXML { 88 | return [[[self class] alloc] initWithData:theData encoding:theEncoding isXML:isDataXML]; 89 | } 90 | 91 | + (TFHpple *) hppleWithData:(NSData *)theData isXML:(BOOL)isDataXML { 92 | return [[self class] hppleWithData:theData encoding:nil isXML:isDataXML]; 93 | } 94 | 95 | + (TFHpple *) hppleWithHTMLData:(NSData *)theData encoding:(NSString *)theEncoding { 96 | return [[self class] hppleWithData:theData encoding:theEncoding isXML:NO]; 97 | } 98 | 99 | + (TFHpple *) hppleWithHTMLData:(NSData *)theData { 100 | return [[self class] hppleWithData:theData encoding:nil isXML:NO]; 101 | } 102 | 103 | + (TFHpple *) hppleWithXMLData:(NSData *)theData encoding:(NSString *)theEncoding { 104 | return [[self class] hppleWithData:theData encoding:theEncoding isXML:YES]; 105 | } 106 | 107 | + (TFHpple *) hppleWithXMLData:(NSData *)theData { 108 | return [[self class] hppleWithData:theData encoding:nil isXML:YES]; 109 | } 110 | 111 | #pragma mark - 112 | 113 | // Returns all elements at xPath. 114 | - (NSArray *) searchWithXPathQuery:(NSString *)xPathOrCSS 115 | { 116 | NSArray * detailNodes = nil; 117 | if (isXML) { 118 | detailNodes = PerformXMLXPathQueryWithEncoding(data, xPathOrCSS, encoding); 119 | } else { 120 | detailNodes = PerformHTMLXPathQueryWithEncoding(data, xPathOrCSS, encoding); 121 | } 122 | 123 | NSMutableArray * hppleElements = [NSMutableArray array]; 124 | for (id node in detailNodes) { 125 | [hppleElements addObject:[TFHppleElement hppleElementWithNode:node isXML:isXML withEncoding:encoding]]; 126 | } 127 | return hppleElements; 128 | } 129 | 130 | // Returns first element at xPath 131 | - (TFHppleElement *) peekAtSearchWithXPathQuery:(NSString *)xPathOrCSS 132 | { 133 | NSArray * elements = [self searchWithXPathQuery:xPathOrCSS]; 134 | if ([elements count] >= 1) { 135 | return [elements objectAtIndex:0]; 136 | } 137 | 138 | return nil; 139 | } 140 | 141 | @end 142 | -------------------------------------------------------------------------------- /ed2kTools/Classes/TFHppleElement.h: -------------------------------------------------------------------------------- 1 | // 2 | // TFHppleElement.h 3 | // Hpple 4 | // 5 | // Created by Geoffrey Grosenbach on 1/31/09. 6 | // 7 | // Copyright (c) 2009 Topfunky Corporation, http://topfunky.com 8 | // 9 | // MIT LICENSE 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining 12 | // a copy of this software and associated documentation files (the 13 | // "Software"), to deal in the Software without restriction, including 14 | // without limitation the rights to use, copy, modify, merge, publish, 15 | // distribute, sublicense, and/or sell copies of the Software, and to 16 | // permit persons to whom the Software is furnished to do so, subject to 17 | // the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be 20 | // included in all copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | 30 | #import 31 | 32 | 33 | @interface TFHppleElement : NSObject 34 | 35 | - (id) initWithNode:(NSDictionary *) theNode isXML:(BOOL)isDataXML withEncoding:(NSString *)theEncoding; 36 | 37 | + (TFHppleElement *) hppleElementWithNode:(NSDictionary *) theNode isXML:(BOOL)isDataXML withEncoding:(NSString *)theEncoding; 38 | 39 | @property (nonatomic, copy, readonly) NSString *raw; 40 | // Returns this tag's innerHTML content. 41 | @property (nonatomic, copy, readonly) NSString *content; 42 | 43 | // Returns the name of the current tag, such as "h3". 44 | @property (nonatomic, copy, readonly) NSString *tagName; 45 | 46 | // Returns tag attributes with name as key and content as value. 47 | // href = 'http://peepcode.com' 48 | // class = 'highlight' 49 | @property (nonatomic, strong, readonly) NSDictionary *attributes; 50 | 51 | // Returns the children of a given node 52 | @property (nonatomic, strong, readonly) NSArray *children; 53 | 54 | // Returns the first child of a given node 55 | @property (nonatomic, strong, readonly) TFHppleElement *firstChild; 56 | 57 | // the parent of a node 58 | @property (nonatomic, unsafe_unretained, readonly) TFHppleElement *parent; 59 | 60 | // Returns YES if the node has any child 61 | // This is more efficient than using the children property since no NSArray is constructed 62 | - (BOOL)hasChildren; 63 | 64 | // Returns YES if this is a text node 65 | - (BOOL)isTextNode; 66 | 67 | // Provides easy access to the content of a specific attribute, 68 | // such as 'href' or 'class'. 69 | - (NSString *) objectForKey:(NSString *) theKey; 70 | 71 | // Returns the children whose tag name equals the given string 72 | // (comparison is performed with NSString's isEqualToString) 73 | // Returns an empty array if no matching child is found 74 | - (NSArray *) childrenWithTagName:(NSString *)tagName; 75 | 76 | // Returns the first child node whose tag name equals the given string 77 | // (comparison is performed with NSString's isEqualToString) 78 | // Returns nil if no matching child is found 79 | - (TFHppleElement *) firstChildWithTagName:(NSString *)tagName; 80 | 81 | // Returns the children whose class equals the given string 82 | // (comparison is performed with NSString's isEqualToString) 83 | // Returns an empty array if no matching child is found 84 | - (NSArray *) childrenWithClassName:(NSString *)className; 85 | 86 | // Returns the first child whose class requals the given string 87 | // (comparison is performed with NSString's isEqualToString) 88 | // Returns nil if no matching child is found 89 | - (TFHppleElement *) firstChildWithClassName:(NSString*)className; 90 | 91 | // Returns the first text node from this element's children 92 | // Returns nil if there is no text node among the children 93 | - (TFHppleElement *) firstTextChild; 94 | 95 | // Returns the string contained by the first text node from this element's children 96 | // Convenience method which can be used instead of firstTextChild.content 97 | - (NSString *) text; 98 | 99 | // Returns elements searched with xpath 100 | - (NSArray *) searchWithXPathQuery:(NSString *)xPathOrCSS; 101 | 102 | // Custom keyed subscripting 103 | - (id)objectForKeyedSubscript:(id)key; 104 | 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /ed2kTools/Classes/TFHppleElement.m: -------------------------------------------------------------------------------- 1 | // 2 | // TFHppleElement.m 3 | // Hpple 4 | // 5 | // Created by Geoffrey Grosenbach on 1/31/09. 6 | // 7 | // Copyright (c) 2009 Topfunky Corporation, http://topfunky.com 8 | // 9 | // MIT LICENSE 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining 12 | // a copy of this software and associated documentation files (the 13 | // "Software"), to deal in the Software without restriction, including 14 | // without limitation the rights to use, copy, modify, merge, publish, 15 | // distribute, sublicense, and/or sell copies of the Software, and to 16 | // permit persons to whom the Software is furnished to do so, subject to 17 | // the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be 20 | // included in all copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | 30 | 31 | #import "TFHppleElement.h" 32 | #import "XPathQuery.h" 33 | 34 | static NSString * const TFHppleNodeContentKey = @"nodeContent"; 35 | static NSString * const TFHppleNodeNameKey = @"nodeName"; 36 | static NSString * const TFHppleNodeChildrenKey = @"nodeChildArray"; 37 | static NSString * const TFHppleNodeAttributeArrayKey = @"nodeAttributeArray"; 38 | static NSString * const TFHppleNodeAttributeNameKey = @"attributeName"; 39 | 40 | static NSString * const TFHppleTextNodeName = @"text"; 41 | 42 | @interface TFHppleElement () 43 | { 44 | NSDictionary * node; 45 | BOOL isXML; 46 | NSString *encoding; 47 | __unsafe_unretained TFHppleElement *parent; 48 | } 49 | 50 | @property (nonatomic, unsafe_unretained, readwrite) TFHppleElement *parent; 51 | 52 | @end 53 | 54 | @implementation TFHppleElement 55 | @synthesize parent; 56 | 57 | 58 | - (id) initWithNode:(NSDictionary *) theNode isXML:(BOOL)isDataXML withEncoding:(NSString *)theEncoding 59 | { 60 | if (!(self = [super init])) 61 | return nil; 62 | 63 | isXML = isDataXML; 64 | node = theNode; 65 | encoding = theEncoding; 66 | 67 | return self; 68 | } 69 | 70 | + (TFHppleElement *) hppleElementWithNode:(NSDictionary *) theNode isXML:(BOOL)isDataXML withEncoding:(NSString *)theEncoding 71 | { 72 | return [[[self class] alloc] initWithNode:theNode isXML:isDataXML withEncoding:theEncoding]; 73 | } 74 | 75 | #pragma mark - 76 | 77 | - (NSString *)raw 78 | { 79 | return [node objectForKey:@"raw"]; 80 | } 81 | 82 | - (NSString *) content 83 | { 84 | return [node objectForKey:TFHppleNodeContentKey]; 85 | } 86 | 87 | 88 | - (NSString *) tagName 89 | { 90 | return [node objectForKey:TFHppleNodeNameKey]; 91 | } 92 | 93 | - (NSArray *) children 94 | { 95 | NSMutableArray *children = [NSMutableArray array]; 96 | for (NSDictionary *child in [node objectForKey:TFHppleNodeChildrenKey]) { 97 | TFHppleElement *element = [TFHppleElement hppleElementWithNode:child isXML:isXML withEncoding:encoding]; 98 | element.parent = self; 99 | [children addObject:element]; 100 | } 101 | return children; 102 | } 103 | 104 | - (TFHppleElement *) firstChild 105 | { 106 | NSArray * children = self.children; 107 | if (children.count) 108 | return [children objectAtIndex:0]; 109 | return nil; 110 | } 111 | 112 | 113 | - (NSDictionary *) attributes 114 | { 115 | NSMutableDictionary * translatedAttributes = [NSMutableDictionary dictionary]; 116 | for (NSDictionary * attributeDict in [node objectForKey:TFHppleNodeAttributeArrayKey]) { 117 | if ([attributeDict objectForKey:TFHppleNodeContentKey] && [attributeDict objectForKey:TFHppleNodeAttributeNameKey]) { 118 | [translatedAttributes setObject:[attributeDict objectForKey:TFHppleNodeContentKey] 119 | forKey:[attributeDict objectForKey:TFHppleNodeAttributeNameKey]]; 120 | } 121 | } 122 | return translatedAttributes; 123 | } 124 | 125 | - (NSString *) objectForKey:(NSString *) theKey 126 | { 127 | return [[self attributes] objectForKey:theKey]; 128 | } 129 | 130 | - (id) description 131 | { 132 | return [node description]; 133 | } 134 | 135 | - (BOOL)hasChildren 136 | { 137 | if ([node objectForKey:TFHppleNodeChildrenKey]) 138 | return YES; 139 | else 140 | return NO; 141 | } 142 | 143 | - (BOOL)isTextNode 144 | { 145 | // we must distinguish between real text nodes and standard nodes with tha name "text" () 146 | // real text nodes must have content 147 | if ([self.tagName isEqualToString:TFHppleTextNodeName] && (self.content)) 148 | return YES; 149 | else 150 | return NO; 151 | } 152 | 153 | - (NSArray*) childrenWithTagName:(NSString*)tagName 154 | { 155 | NSMutableArray* matches = [NSMutableArray array]; 156 | 157 | for (TFHppleElement* child in self.children) 158 | { 159 | if ([child.tagName isEqualToString:tagName]) 160 | [matches addObject:child]; 161 | } 162 | 163 | return matches; 164 | } 165 | 166 | - (TFHppleElement *) firstChildWithTagName:(NSString*)tagName 167 | { 168 | for (TFHppleElement* child in self.children) 169 | { 170 | if ([child.tagName isEqualToString:tagName]) 171 | return child; 172 | } 173 | 174 | return nil; 175 | } 176 | 177 | - (NSArray*) childrenWithClassName:(NSString*)className 178 | { 179 | NSMutableArray* matches = [NSMutableArray array]; 180 | 181 | for (TFHppleElement* child in self.children) 182 | { 183 | if ([[child objectForKey:@"class"] isEqualToString:className]) 184 | [matches addObject:child]; 185 | } 186 | 187 | return matches; 188 | } 189 | 190 | - (TFHppleElement *) firstChildWithClassName:(NSString*)className 191 | { 192 | for (TFHppleElement* child in self.children) 193 | { 194 | if ([[child objectForKey:@"class"] isEqualToString:className]) 195 | return child; 196 | } 197 | 198 | return nil; 199 | } 200 | 201 | - (TFHppleElement *) firstTextChild 202 | { 203 | for (TFHppleElement* child in self.children) 204 | { 205 | if ([child isTextNode]) 206 | return child; 207 | } 208 | 209 | return [self firstChildWithTagName:TFHppleTextNodeName]; 210 | } 211 | 212 | - (NSString *) text 213 | { 214 | return self.firstTextChild.content; 215 | } 216 | 217 | // Returns all elements at xPath. 218 | - (NSArray *) searchWithXPathQuery:(NSString *)xPathOrCSS 219 | { 220 | 221 | NSData *data = [self.raw dataUsingEncoding:NSUTF8StringEncoding]; 222 | 223 | NSArray * detailNodes = nil; 224 | if (isXML) { 225 | detailNodes = PerformXMLXPathQueryWithEncoding(data, xPathOrCSS, encoding); 226 | } else { 227 | detailNodes = PerformHTMLXPathQueryWithEncoding(data, xPathOrCSS, encoding); 228 | } 229 | 230 | NSMutableArray * hppleElements = [NSMutableArray array]; 231 | for (id newNode in detailNodes) { 232 | [hppleElements addObject:[TFHppleElement hppleElementWithNode:newNode isXML:isXML withEncoding:encoding]]; 233 | } 234 | return hppleElements; 235 | } 236 | 237 | // Custom keyed subscripting 238 | - (id)objectForKeyedSubscript:(id)key 239 | { 240 | return [self objectForKey:key]; 241 | } 242 | 243 | @end 244 | -------------------------------------------------------------------------------- /ed2kTools/Classes/XPathQuery.h: -------------------------------------------------------------------------------- 1 | // 2 | // XPathQuery.h 3 | // FuelFinder 4 | // 5 | // Created by Matt Gallagher on 4/08/08. 6 | // Copyright 2008 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NSArray *PerformHTMLXPathQuery(NSData *document, NSString *query); 12 | NSArray *PerformHTMLXPathQueryWithEncoding(NSData *document, NSString *query,NSString *encoding); 13 | NSArray *PerformXMLXPathQuery(NSData *document, NSString *query); 14 | NSArray *PerformXMLXPathQueryWithEncoding(NSData *document, NSString *query,NSString *encoding); 15 | -------------------------------------------------------------------------------- /ed2kTools/Classes/XPathQuery.m: -------------------------------------------------------------------------------- 1 | // 2 | // XPathQuery.m 3 | // FuelFinder 4 | // 5 | // Created by Matt Gallagher on 4/08/08. 6 | // Copyright 2008 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "XPathQuery.h" 10 | 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | 17 | NSDictionary *DictionaryForNode(xmlNodePtr currentNode, NSMutableDictionary *parentResult,BOOL parentContent); 18 | NSArray *PerformXPathQuery(xmlDocPtr doc, NSString *query); 19 | 20 | NSDictionary *DictionaryForNode(xmlNodePtr currentNode, NSMutableDictionary *parentResult,BOOL parentContent) 21 | { 22 | NSMutableDictionary *resultForNode = [NSMutableDictionary dictionary]; 23 | if (currentNode->name) { 24 | NSString *currentNodeContent = [NSString stringWithCString:(const char *)currentNode->name 25 | encoding:NSUTF8StringEncoding]; 26 | resultForNode[@"nodeName"] = currentNodeContent; 27 | } 28 | 29 | xmlChar *nodeContent = xmlNodeGetContent(currentNode); 30 | if (nodeContent != NULL) { 31 | NSString *currentNodeContent = [NSString stringWithCString:(const char *)nodeContent 32 | encoding:NSUTF8StringEncoding]; 33 | if ([resultForNode[@"nodeName"] isEqual:@"text"] && parentResult) { 34 | if (parentContent) { 35 | NSCharacterSet *charactersToTrim = [NSCharacterSet whitespaceAndNewlineCharacterSet]; 36 | parentResult[@"nodeContent"] = [currentNodeContent stringByTrimmingCharactersInSet:charactersToTrim]; 37 | return nil; 38 | } 39 | if (currentNodeContent != nil) { 40 | resultForNode[@"nodeContent"] = currentNodeContent; 41 | } 42 | return resultForNode; 43 | } else { 44 | resultForNode[@"nodeContent"] = currentNodeContent; 45 | } 46 | xmlFree(nodeContent); 47 | } 48 | 49 | xmlAttr *attribute = currentNode->properties; 50 | if (attribute) { 51 | NSMutableArray *attributeArray = [NSMutableArray array]; 52 | while (attribute) { 53 | NSMutableDictionary *attributeDictionary = [NSMutableDictionary dictionary]; 54 | NSString *attributeName = [NSString stringWithCString:(const char *)attribute->name 55 | encoding:NSUTF8StringEncoding]; 56 | if (attributeName) { 57 | attributeDictionary[@"attributeName"] = attributeName; 58 | } 59 | 60 | if (attribute->children) { 61 | NSDictionary *childDictionary = DictionaryForNode(attribute->children, attributeDictionary, true); 62 | if (childDictionary) { 63 | attributeDictionary[@"attributeContent"] = childDictionary; 64 | } 65 | } 66 | 67 | if ([attributeDictionary count] > 0) { 68 | [attributeArray addObject:attributeDictionary]; 69 | } 70 | attribute = attribute->next; 71 | } 72 | 73 | if ([attributeArray count] > 0) { 74 | resultForNode[@"nodeAttributeArray"] = attributeArray; 75 | } 76 | } 77 | 78 | xmlNodePtr childNode = currentNode->children; 79 | if (childNode) { 80 | NSMutableArray *childContentArray = [NSMutableArray array]; 81 | while (childNode) { 82 | NSDictionary *childDictionary = DictionaryForNode(childNode, resultForNode,false); 83 | if (childDictionary) { 84 | [childContentArray addObject:childDictionary]; 85 | } 86 | childNode = childNode->next; 87 | } 88 | if ([childContentArray count] > 0) { 89 | resultForNode[@"nodeChildArray"] = childContentArray; 90 | } 91 | } 92 | 93 | xmlBufferPtr buffer = xmlBufferCreate(); 94 | xmlNodeDump(buffer, currentNode->doc, currentNode, 0, 0); 95 | NSString *rawContent = [NSString stringWithCString:(const char *)buffer->content encoding:NSUTF8StringEncoding]; 96 | if (rawContent != nil) { 97 | resultForNode[@"raw"] = rawContent; 98 | } 99 | xmlBufferFree(buffer); 100 | return resultForNode; 101 | } 102 | 103 | NSArray *PerformXPathQuery(xmlDocPtr doc, NSString *query) 104 | { 105 | xmlXPathContextPtr xpathCtx; 106 | xmlXPathObjectPtr xpathObj; 107 | 108 | /* Make sure that passed query is non-nil and is NSString object */ 109 | if (query == nil || ![query isKindOfClass:[NSString class]]) { 110 | return nil; 111 | } 112 | 113 | /* Create xpath evaluation context */ 114 | xpathCtx = xmlXPathNewContext(doc); 115 | if(xpathCtx == NULL) { 116 | NSLog(@"Unable to create XPath context."); 117 | return nil; 118 | } 119 | 120 | /* Evaluate xpath expression */ 121 | xpathObj = xmlXPathEvalExpression((xmlChar *)[query cStringUsingEncoding:NSUTF8StringEncoding], xpathCtx); 122 | if(xpathObj == NULL) { 123 | NSLog(@"Unable to evaluate XPath."); 124 | xmlXPathFreeContext(xpathCtx); 125 | return nil; 126 | } 127 | 128 | xmlNodeSetPtr nodes = xpathObj->nodesetval; 129 | if (!nodes) { 130 | NSLog(@"Nodes was nil."); 131 | xmlXPathFreeObject(xpathObj); 132 | xmlXPathFreeContext(xpathCtx); 133 | return nil; 134 | } 135 | 136 | NSMutableArray *resultNodes = [NSMutableArray array]; 137 | for (NSInteger i = 0; i < nodes->nodeNr; i++) { 138 | NSDictionary *nodeDictionary = DictionaryForNode(nodes->nodeTab[i], nil,false); 139 | if (nodeDictionary) { 140 | [resultNodes addObject:nodeDictionary]; 141 | } 142 | } 143 | 144 | /* Cleanup */ 145 | xmlXPathFreeObject(xpathObj); 146 | xmlXPathFreeContext(xpathCtx); 147 | 148 | return resultNodes; 149 | } 150 | 151 | NSArray *PerformHTMLXPathQuery(NSData *document, NSString *query) { 152 | return PerformHTMLXPathQueryWithEncoding(document, query, nil); 153 | } 154 | 155 | NSArray *PerformHTMLXPathQueryWithEncoding(NSData *document, NSString *query,NSString *encoding) 156 | { 157 | xmlDocPtr doc; 158 | 159 | /* Load XML document */ 160 | const char *encoded = encoding ? [encoding cStringUsingEncoding:NSUTF8StringEncoding] : NULL; 161 | 162 | doc = htmlReadMemory([document bytes], (int)[document length], "", encoded, HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR); 163 | if (doc == NULL) { 164 | NSLog(@"Unable to parse."); 165 | return nil; 166 | } 167 | 168 | NSArray *result = PerformXPathQuery(doc, query); 169 | xmlFreeDoc(doc); 170 | 171 | return result; 172 | } 173 | 174 | NSArray *PerformXMLXPathQuery(NSData *document, NSString *query) { 175 | return PerformXMLXPathQueryWithEncoding(document, query, nil); 176 | } 177 | 178 | NSArray *PerformXMLXPathQueryWithEncoding(NSData *document, NSString *query,NSString *encoding) 179 | { 180 | xmlDocPtr doc; 181 | 182 | /* Load XML document */ 183 | const char *encoded = encoding ? [encoding cStringUsingEncoding:NSUTF8StringEncoding] : NULL; 184 | 185 | doc = xmlReadMemory([document bytes], (int)[document length], "", encoded, XML_PARSE_RECOVER); 186 | 187 | if (doc == NULL) { 188 | NSLog(@"Unable to parse."); 189 | return nil; 190 | } 191 | 192 | NSArray *result = PerformXPathQuery(doc, query); 193 | xmlFreeDoc(doc); 194 | 195 | return result; 196 | } 197 | -------------------------------------------------------------------------------- /ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youusername/ed2kTools/210e4dcab2ed2247c6db624e32af326e7ee52aae/ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-1.png -------------------------------------------------------------------------------- /ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youusername/ed2kTools/210e4dcab2ed2247c6db624e32af326e7ee52aae/ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-2.png -------------------------------------------------------------------------------- /ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youusername/ed2kTools/210e4dcab2ed2247c6db624e32af326e7ee52aae/ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-3.png -------------------------------------------------------------------------------- /ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youusername/ed2kTools/210e4dcab2ed2247c6db624e32af326e7ee52aae/ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-4.png -------------------------------------------------------------------------------- /ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youusername/ed2kTools/210e4dcab2ed2247c6db624e32af326e7ee52aae/ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-5.png -------------------------------------------------------------------------------- /ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youusername/ed2kTools/210e4dcab2ed2247c6db624e32af326e7ee52aae/ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-6.png -------------------------------------------------------------------------------- /ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youusername/ed2kTools/210e4dcab2ed2247c6db624e32af326e7ee52aae/ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8-7.png -------------------------------------------------------------------------------- /ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youusername/ed2kTools/210e4dcab2ed2247c6db624e32af326e7ee52aae/ed2kTools/Images.xcassets/AppIcon.appiconset/09223K643-8.png -------------------------------------------------------------------------------- /ed2kTools/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "09223K643-8-6.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "09223K643-8-5.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "09223K643-8-7.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "09223K643-8-4.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "09223K643-8-3.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "09223K643-8-2.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "09223K643-8-1.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "09223K643-8.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "idiom" : "mac", 53 | "size" : "512x512", 54 | "scale" : "1x" 55 | }, 56 | { 57 | "idiom" : "mac", 58 | "size" : "512x512", 59 | "scale" : "2x" 60 | } 61 | ], 62 | "info" : { 63 | "version" : 1, 64 | "author" : "xcode" 65 | } 66 | } -------------------------------------------------------------------------------- /ed2kTools/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ed2k提取器 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.1125 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | 32 | NSHumanReadableCopyright 33 | Copyright © 2015年 Mac. All rights reserved. 34 | NSMainStoryboardFile 35 | Main 36 | NSPrincipalClass 37 | NSApplication 38 | 39 | 40 | -------------------------------------------------------------------------------- /ed2kTools/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ed2kTools 4 | // 5 | // Created by Mac on 15/10/13. 6 | // Copyright (c) 2015年 Mac. All rights reserved. 7 | // 8 | 9 | #import 10 | @interface ViewController : NSViewController 11 | @property (weak) IBOutlet NSTextField *getURLField; 12 | @property (weak) IBOutlet NSSearchField *getSearchField; 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ed2kTools/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // ed2kTools 4 | // 5 | // Created by Mac on 15/10/13. 6 | // Copyright (c) 2015年 Mac. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "TFHpple.h" 11 | //#import "AFOnoResponseSerializer.h" 12 | //#import "Ono.h" 13 | #import "ed2kClass.h" 14 | @implementation ViewController{ 15 | NSMutableArray*ed2kArray; 16 | TFHpple *xpathparser; 17 | __weak IBOutlet NSTableView *EtableView; 18 | } 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | 23 | // self.manager = [AFHTTPRequestOperationManager manager]; 24 | // self.manager.responseSerializer = [AFOnoResponseSerializer HTMLResponseSerializer]; 25 | ed2kArray = [[NSMutableArray alloc]init]; 26 | xpathparser=[[TFHpple alloc]init]; 27 | //setAction单击选择事件 28 | [EtableView setAction:NSSelectorFromString(@"SelectorClick:")]; 29 | //setDoubleAction双击选择事件 30 | [EtableView setDoubleAction:NSSelectorFromString(@"doubleClick:")]; 31 | 32 | 33 | // self.getURLField.stringValue=@"http://tieba.baidu.com/p/2201917869"; 34 | 35 | } 36 | 37 | - (void)SelectorClick:(id)sender 38 | 39 | { 40 | // 单击选择事件 41 | // http://www.ed2000.com/ShowFile.asp?vid=2894968 42 | NSInteger rowNumber = [EtableView clickedRow]; 43 | if (rowNumber==-1) { 44 | for (ed2kClass*ed2k in ed2kArray) { 45 | ed2k.box=ed2k.box==1?0:1; 46 | } 47 | }else{ 48 | ed2kClass*ed2k=ed2kArray[rowNumber]; 49 | ed2k.box=ed2k.box==1?0:1; 50 | 51 | NSLog(@"Selector Clicked.%ld / %@",rowNumber,ed2k.ed2k); 52 | } 53 | [EtableView reloadData]; 54 | 55 | 56 | 57 | } 58 | - (void)doubleClick:(id)sender 59 | 60 | { 61 | // 双击选择事件 62 | NSInteger rowNumber = [EtableView clickedRow]; 63 | 64 | NSLog(@"Double Clicked.%ld ",rowNumber); 65 | 66 | } 67 | -(void)viewWillAppear{ 68 | // 69 | // NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; 70 | // NSString *plainText = [[pasteboard readObjectsForClasses:@[[NSString class]] options:nil] firstObject]; 71 | // if(self.getURLField.stringValue.length==0||self.getURLField.stringValue.length<400||plainText!=nil){ 72 | // self.getURLField.stringValue=plainText; 73 | // } 74 | } 75 | - (IBAction)copySelectorEd2k:(id)sender { 76 | NSString*str=[[NSString alloc]init]; 77 | for (ed2kClass*ed2k in ed2kArray) { 78 | if (ed2k.box==1) { 79 | str=[str stringByAppendingString:[NSString stringWithFormat:@"\n%@",ed2k.ed2k]]; 80 | } 81 | } 82 | [self setPasteboard:str]; 83 | } 84 | #pragma mark 跳转到weibo 85 | - (void)openURL:(NSString *)url inBackground:(BOOL)background 86 | { 87 | if (background) 88 | { 89 | NSArray* urls = [NSArray arrayWithObject:[NSURL URLWithString:url]]; 90 | [[NSWorkspace sharedWorkspace] openURLs:urls withAppBundleIdentifier:nil options:NSWorkspaceLaunchWithoutActivation additionalEventParamDescriptor:nil launchIdentifiers:nil]; 91 | } 92 | else 93 | { 94 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]]; 95 | } 96 | } 97 | - (IBAction)pushWibo:(id)sender { 98 | 99 | NSArray* urls = [NSArray arrayWithObject:[NSURL URLWithString:@"http://weibo.com/u/2689574923"]]; 100 | [[NSWorkspace sharedWorkspace] openURLs:urls withAppBundleIdentifier:nil options:NSWorkspaceLaunchWithoutActivation additionalEventParamDescriptor:nil launchIdentifiers:nil]; 101 | 102 | } 103 | - (IBAction)copyAllEd2k:(id)sender { 104 | NSString*str=[[NSString alloc]init]; 105 | for (ed2kClass*ed2k in ed2kArray) { 106 | str=[str stringByAppendingString:[NSString stringWithFormat:@"\n%@",ed2k.ed2k]]; 107 | } 108 | [self setPasteboard:str]; 109 | } 110 | 111 | - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 112 | { 113 | ed2kClass*ed2k; 114 | if([[tableColumn identifier] isEqualToString:@"number"]){ 115 | return [NSString stringWithFormat:@"%ld",row+1]; 116 | } 117 | else if ([[tableColumn identifier] isEqualToString:@"ed2k"]){ 118 | ed2k=ed2kArray[row]; 119 | return ed2k.Name; 120 | } 121 | else if ([[tableColumn identifier] isEqualToString:@"box"]){ 122 | ed2k=ed2kArray[row]; 123 | return [NSString stringWithFormat:@"%ld",ed2k.box]; 124 | } 125 | else{ 126 | return nil; 127 | } 128 | } 129 | 130 | -(void)setPasteboard:(NSString*)text{ 131 | NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; 132 | 133 | [self writeToPasteboard:pasteboard withString:text]; 134 | } 135 | -(NSString*)FiltrationURL:(NSString*)url{ 136 | url=[url stringByReplacingOccurrencesOfString:@" " withString:@""]; 137 | url=[url stringByReplacingOccurrencesOfString:@"\n" withString:@""]; 138 | return url; 139 | } 140 | - (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row 141 | { 142 | return YES; 143 | } 144 | - (void)writeToPasteboard:(NSPasteboard *)pb withString:string{ 145 | [pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] 146 | owner:self]; 147 | [pb setString:string forType:NSStringPboardType]; 148 | } 149 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { 150 | return [ed2kArray count]; 151 | } 152 | - (IBAction)GoAction:(id)sender { 153 | // http://cn163.net/archives/140 154 | // http://cn163.net/archives/138 155 | 156 | 157 | if (self.getURLField.stringValue.length>5) { 158 | [ed2kArray removeAllObjects]; 159 | // [ed2kArray addObjectsFromArray:[self getEd2kSetUrl:[self FiltrationURL:self.getURLField.stringValue]]]; 160 | [self getEd2kSetUrl:self.getURLField.stringValue]; 161 | 162 | }else if (self.getSearchField.stringValue.length>5){ 163 | // [ed2kArray removeAllObjects]; 164 | // [EtableView reloadData]; 165 | }else{ 166 | NSAlert *alert = [NSAlert alertWithMessageText:@"你确定你输入了搜索名字或地址吗?" 167 | defaultButton:@"OK" 168 | alternateButton:@"Cancel" 169 | otherButton:nil 170 | informativeTextWithFormat:@"如果你确定有输入但程序没有反应请联系我告知BUG!"]; 171 | [alert beginSheetModalForWindow:self.view.window 172 | modalDelegate:self didEndSelector:nil 173 | contextInfo:nil]; 174 | 175 | } 176 | 177 | } 178 | -(void)getEd2kSetUrl:(NSString*)url{ 179 | 180 | NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]]; 181 | NSURLSession * session = [NSURLSession sharedSession]; 182 | NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 183 | dispatch_async(dispatch_queue_create("download html queue", nil), ^{ 184 | if (data.length<100) { 185 | 186 | } 187 | 188 | [xpathparser setValue:data forKey:@"data"]; 189 | NSString*ed2k; 190 | NSArray*liS=[xpathparser searchWithXPathQuery:@"//a[@href]"]; 191 | NSString* strClear; 192 | NSRange range; 193 | BOOL isAdd = NO; 194 | for (TFHppleElement*tf in liS) { 195 | if (tf.raw.length>200) { 196 | 197 | if ([[tf.raw componentsSeparatedByString:@"ed2k://"] count]>=2) { 198 | // 查找ed2k链接 199 | // user = @"ed2k://.*.\\|\\/"; 200 | // range = [tf.raw rangeOfString:user options:NSRegularExpressionSearch]; 201 | // strClear=[NSString stringWithFormat:@"%@",[tf.raw substringWithRange:range]]; 202 | strClear = [self TextrangeOfString:tf.raw setRegularExpressions:@"ed2k://.*.\\|\\/"]; 203 | NSArray*strClearArray=[strClear componentsSeparatedByString:@"|/"]; 204 | if (strClearArray.count<2) { 205 | ed2k=[tf.raw substringWithRange:range]; 206 | }else{ 207 | ed2k=[NSString stringWithFormat:@"%@|/",strClearArray[0]]; 208 | } 209 | isAdd = YES; 210 | 211 | }else if ([[tf.raw componentsSeparatedByString:@"magnet:?"] count]>=2){ 212 | // 查找磁力链接 213 | // user = @"magnet:?[^\"]+"; 214 | // range = [tf.raw rangeOfString:user options:NSRegularExpressionSearch]; 215 | // strClear = [NSString stringWithFormat:@"%@",[tf.raw substringWithRange:range]]; 216 | // ed2k = strClear; 217 | ed2k = [self TextrangeOfString:tf.raw setRegularExpressions:@"magnet:?[^\"]+"]; 218 | isAdd = YES; 219 | } 220 | 221 | 222 | if (range.location != NSNotFound && isAdd) { 223 | // 排除空数据 224 | ed2kClass*e=[[ed2kClass alloc]init]; 225 | e.ed2k=ed2k; 226 | e.Name=[self searchEd2kName:ed2k]; 227 | 228 | [ed2kArray addObject:e]; 229 | } 230 | isAdd = NO; 231 | } 232 | } 233 | 234 | 235 | if (ed2kArray.count<=0) { 236 | // 查找非标签内的ed2k 237 | [ed2kArray addObjectsFromArray:[self getNotLabeWeb:[xpathparser searchWithXPathQuery:@"/*"]]]; 238 | } 239 | dispatch_async(dispatch_get_main_queue(), ^{ 240 | // 更新界面 241 | 242 | [EtableView reloadData]; 243 | }); 244 | }); 245 | }]; 246 | [dataTask resume]; 247 | 248 | 249 | // return ListArray; 250 | } 251 | 252 | -(NSMutableArray*)getNotLabeWeb:(NSArray*)array{ 253 | // 整理去重 254 | NSMutableSet*setEd2k=[[NSMutableSet alloc]init]; 255 | for (TFHppleElement*tf in array) { 256 | NSArray*ed2kA=[tf.raw componentsSeparatedByString:@"|/"]; 257 | for (NSString*isEd2k in ed2kA) { 258 | if ([self isEd2k:[NSString stringWithFormat:@"%@|/",isEd2k]]) 259 | { 260 | NSString*clearEd2k = [self clearEd2kSrt:[NSString stringWithFormat:@"%@|/",isEd2k]]; 261 | [setEd2k addObject:[self clearEd2kSrt:clearEd2k]]; 262 | } 263 | } 264 | } 265 | NSArray *sortDesc = @[[[NSSortDescriptor alloc] initWithKey:nil ascending:YES]]; 266 | NSArray *sortSetArray = [setEd2k sortedArrayUsingDescriptors:sortDesc]; 267 | // 生成对象加入数组 268 | NSMutableArray*arr=[[NSMutableArray alloc]init]; 269 | for (NSString*Ed2k in sortSetArray) { 270 | ed2kClass*e=[[ed2kClass alloc]init]; 271 | e.ed2k=Ed2k; 272 | e.Name=[self searchEd2kName:Ed2k]; 273 | [arr addObject:e]; 274 | } 275 | 276 | return arr; 277 | } 278 | -(NSString*)clearEd2kSrt:(NSString*)ed2kstr{ 279 | // 清理ed2k前后的多余字符 280 | NSRange range = [ed2kstr rangeOfString:@"ed2k://"];//匹配得到的下标 281 | NSRange range2 = [ed2kstr rangeOfString:@"|/"];//匹配得到的下标 282 | // NSString*clear1=[] 283 | return [[ed2kstr substringFromIndex:range.location] substringToIndex:range2.length+range2.location-range.location]; 284 | } 285 | -(BOOL)isEd2k:(NSString*)str{ 286 | NSRange range = [str rangeOfString:@"ed2k://.*.\\|\\/" options:NSRegularExpressionSearch]; 287 | if (range.length>10) { 288 | return YES; 289 | }else{ 290 | return NO; 291 | } 292 | } 293 | -(NSString*)TextrangeOfString:(NSString*)rangeStr setRegularExpressions:(NSString*)RegularExpressions{ 294 | 295 | NSRange range = [rangeStr rangeOfString:RegularExpressions options:NSRegularExpressionSearch]; 296 | 297 | return [NSString stringWithFormat:@"%@",[rangeStr substringWithRange:range]]; 298 | } 299 | 300 | -(NSString*)searchEd2kName:(NSString*)ed2k{ 301 | // 查找ed2k文件名 302 | NSArray*strClearArray=[ed2k componentsSeparatedByString:@"|"]; 303 | if (strClearArray.count<2) { 304 | return ed2k; 305 | }else{ 306 | NSString*name=[strClearArray[2] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 307 | if (name.length<2) { 308 | // 防止 309 | return ed2k; 310 | }else{ 311 | return name; 312 | } 313 | } 314 | } 315 | - (void)setRepresentedObject:(id)representedObject { 316 | [super setRepresentedObject:representedObject]; 317 | 318 | // Update the view, if already loaded. 319 | } 320 | 321 | @end 322 | -------------------------------------------------------------------------------- /ed2kTools/WindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // WindowController.h 3 | // ed2kTools 4 | // 5 | // Created by phlx-mac1 on 2016/11/25. 6 | // Copyright © 2016年 Mac. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WindowController : NSWindowController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ed2kTools/WindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // WindowController.m 3 | // ed2kTools 4 | // 5 | // Created by phlx-mac1 on 2016/11/25. 6 | // Copyright © 2016年 Mac. All rights reserved. 7 | // 8 | 9 | #import "WindowController.h" 10 | #import "AppDelegate.h" 11 | 12 | @interface WindowController () 13 | @property BOOL mouseDownInTopToolBar; 14 | @property (assign) NSPoint initialLocation; 15 | 16 | @end 17 | 18 | @implementation WindowController 19 | 20 | - (void)windowDidLoad { 21 | [super windowDidLoad]; 22 | AppDelegate* app =(AppDelegate*)[NSApplication sharedApplication].delegate; 23 | app.RootWindow = self.window; 24 | 25 | // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. 26 | } 27 | - (void)mouseDown:(NSEvent *)theEvent 28 | { 29 | self.initialLocation = [theEvent locationInWindow]; 30 | NSRect windowFrame = [self.window frame]; 31 | CGFloat heightOfTitleBarAndTopToolBar = 65; 32 | NSRect titleFrame = NSMakeRect(0, windowFrame.size.height-heightOfTitleBarAndTopToolBar, windowFrame.size.width, heightOfTitleBarAndTopToolBar); 33 | 34 | if(NSPointInRect(self.initialLocation, titleFrame)) 35 | { 36 | self.mouseDownInTopToolBar = YES; 37 | NSLog(@"Mouse IN"); 38 | } 39 | } 40 | 41 | -(void)mouseUp:(NSEvent *)theEvent 42 | { 43 | self.mouseDownInTopToolBar = NO; 44 | NSLog(@"Mouse UP"); 45 | } 46 | 47 | - (void)mouseDragged:(NSEvent *)theEvent 48 | { 49 | if( self.mouseDownInTopToolBar ) 50 | { 51 | NSRect screenVisibleFrame = [[NSScreen mainScreen] visibleFrame]; 52 | NSRect windowFrame = [self.window frame]; 53 | 54 | NSPoint newOrigin = windowFrame.origin; 55 | NSPoint currentLocation = [theEvent locationInWindow]; 56 | 57 | 58 | 59 | // Update the origin with the difference between the new mouse location and the old mouse location. 60 | newOrigin.x += (currentLocation.x - self.initialLocation.x); 61 | newOrigin.y += (currentLocation.y - self.initialLocation.y); 62 | 63 | // Don't let window get dragged up under the menu bar 64 | if ((newOrigin.y + windowFrame.size.height) > (screenVisibleFrame.origin.y + screenVisibleFrame.size.height)) { 65 | newOrigin.y = screenVisibleFrame.origin.y + (screenVisibleFrame.size.height - windowFrame.size.height); 66 | } 67 | 68 | [self.window setFrameOrigin:newOrigin]; 69 | } 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /ed2kTools/ed2kClass.h: -------------------------------------------------------------------------------- 1 | // 2 | // ed2kClass.h 3 | // ed2kTools 4 | // 5 | // Created by Mac on 15/10/16. 6 | // Copyright © 2015年 Mac. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ed2kClass : NSObject 12 | @property(nonatomic,copy)NSString*ed2k; 13 | @property(nonatomic,copy)NSString*Name; 14 | @property(nonatomic,assign)NSInteger box; 15 | 16 | 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /ed2kTools/ed2kClass.m: -------------------------------------------------------------------------------- 1 | // 2 | // ed2kClass.m 3 | // ed2kTools 4 | // 5 | // Created by Mac on 15/10/16. 6 | // Copyright © 2015年 Mac. All rights reserved. 7 | // 8 | 9 | #import "ed2kClass.h" 10 | 11 | @implementation ed2kClass 12 | -(instancetype)init{ 13 | self = [super init]; 14 | if (self) { 15 | _box=1; 16 | } 17 | return self; 18 | } 19 | @end 20 | -------------------------------------------------------------------------------- /ed2kTools/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ed2kTools 4 | // 5 | // Created by Mac on 15/10/13. 6 | // Copyright (c) 2015年 Mac. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } -------------------------------------------------------------------------------- /ed2kTools/weibo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youusername/ed2kTools/210e4dcab2ed2247c6db624e32af326e7ee52aae/ed2kTools/weibo.png -------------------------------------------------------------------------------- /ed2kToolsTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ed2kToolsTests/ed2kToolsTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ed2kToolsTests.m 3 | // ed2kToolsTests 4 | // 5 | // Created by Mac on 15/10/13. 6 | // Copyright (c) 2015年 Mac. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface ed2kToolsTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation ed2kToolsTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | --------------------------------------------------------------------------------