Latest commit

History

50 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

DeveloperHit

iOSSwiftGoNode

After exploring some Web APIs associated with the chosen topic, only a few websites provide friendly APIs, especially when an XML format data response is expected. Therefore we decided to build our own APIs by parsing HTML pages responded from target websites:

  • Github

    Github trending exhibits some potential open source projects, however, there are only APIs for specific repository and user. So we will build an unofficial XML-based backend.

  • V2EX

    V2EX is a community of technology and design. It provides some APIs for getting latest posts.

  • Gank

    Gank.io is a website which provides some interesting frameworks and projects for programmers. Thus, it also pushes some news in software engineering.

  • Zhihu

    Zhihu may be the biggest Q&A community in China. We will write a backend with RESTful API, which providing some development-related topic content.

The frontend will integrate lastest and hot information in a list for users. And I plan to implement it on Web, iOS and Android platform.

Backend

ContentURL
GitHubhttp://115.159.1.222:8000/github
Zhihuhttp://115.159.1.222:3001/topic
V2EXhttps://www.v2ex.com/api/topics/hot.json
Gankhttp://gank.io/api/day/2015/08/07

GitHub

How to Run

go get github.com/zjzsliyang/go-trending
cd DeveloperHit/Backend
go build
./Backend
# to run in the background# nohup ./Backend &

It will run in the 8000 port with the url /github.

Implement

First, to access GitHub data in https://github.com/trending, I reference a web crawler repo and fork it to fix bugs GitHub new trending page via Go. In the backend part, I create a corresponding data structure to store the GitHub data like Developer, Project, Projects. You can find XML Schema in github.xsd.

One shortcoming is that after getting the request from frontend to crawler takes too long, and cache in frontend or distributed crawler is in the plan.

To produce the XML format data, I import encoding/xml, which is called as followings:

funcTrend(res http.ResponseWriter, req*http.Request) {
trend:=trending.NewTrending()
xsiUrl:="http://www.w3.org/2001/XMLSchema-instance"xmlUrl:="https://github.com/zjzsliyang/DeveloperHit/raw/master/Backend/github.xsd"projects, err:=trend.GetProjects(trending.TimeToday, "")
iferr!=nil {
log.Fatal(err)
}
dataProjects:=&Projects{Version: "1", XsiUrl: xsiUrl, XmlUrl: xmlUrl}
for_, project:=rangeprojects {
dataProject:=Project{Name: project.Name, Owner: project.Owner, RepositoryName: project.RepositoryName,
Description: project.Description, Language: project.Language, Stars: project.Stars}
ifproject.URL==nil {
dataProject.URL=""
} else {
dataProject.URL=project.URL.String()
}
ifproject.ContributorURL==nil {
dataProject.ContributorURL=""
} else {
dataProject.ContributorURL=project.ContributorURL.String()
}
for_, contributor:=rangeproject.Contributor {
dataDeveloper:=Developer{ID: contributor.ID, DisplayName: contributor.DisplayName, FullName: contributor.FullName,
URL: contributor.URL.String(), Avatar: contributor.Avatar.String()}
dataProject.Contributor=append(dataProject.Contributor, dataDeveloper)
}
dataProjects.Project=append(dataProjects.Project, dataProject)
}
res.Write([]byte(xml.Header))
output, err:=xml.MarshalIndent(dataProjects, " ", " ")
iferr!=nil {
log.Fatal(err)
}
res.Write(output)
}

Zhihu

Repo: https://github.com/lisirrx/ZhihuApiBackend

How to Run

npm install
npm start

It will run in the 3001 port with the url /topic.

Frontend

Web

Repo: https://github.com/lisirrx/Vue-DeveloperHit

iOS

How to Run

CocoaPods is a dependency manager for Cocoa projects. Run the following command to install the dependency.

cd DeveloperHit/iOS/DeveloperHit
pod install

Screenshot

iOS-GitHubiOS-Zhihu
iOS-V2EXiOS-Gank
iOS-detail_1iOS-detail_2

Implement

iOS part uses MVVM architecture to decouple views and view models. Thus, to satisfy an information aggregation demand, I use table view design widely.

To parse XML data, I call the native XMLParser function in the viewDidLoad stage as follows:

func parser(_ parser:XMLParser, didStartElement elementName:String, namespaceURI:String?, qualifiedName qName:String?, attributes attributeDict:[String:String]=[:]){}
func parser(_ parser:XMLParser, didEndElement elementName:String, namespaceURI:String?, qualifiedName qName:String?){}
func parser(_ parser:XMLParser, foundCharacters string:String){}

The first function will be called when it starts to parse an XML element, I get the XML element node name and init for the data. In the second function, which will be called after parsing the element, so I assign and store the data. The third function is the parse phase function, to reduce the code amount and a better design, I use KVC(Key-Value Coding) which is a mechanism enabled by the NSKeyValueCoding informal protocol that objects adopt to provide indirect access to their properties. When an object is key-value coding compliant, its properties are addressable via string parameters through a concise, uniform messaging interface. This indirect access mechanism supplements the direct access afforded by instance variables and their associated accessor methods. You can find these code here.

To parse JSON data, I use a famous library called Alamofire. Take GankViewController for example:

func requestGank(){Alamofire.request(ServiceBase.GankUrl).response{(response)inletjson=JSON(data: response.data!)forcategoryinself.categorys {vartempGank:[Gank]=[]for(_, subJson):(String,JSON)injson["results"][category]{letgank=Gank(id:subJson["_id"].string!, createAt:subJson["createdAt"].string!, desc:subJson["desc"].string!, publishedAt:subJson["publishedAt"].string!, type:subJson["type"].string!, url:subJson["url"].string!, used:subJson["used"].bool!, who:subJson["who"].string!)
tempGank.append(gank)}self.ganks.append(tempGank)}self.initGankTableView()}}

In the request function, it will callback when it gets the response. I index for the key and store the value.

Android

Repo: https://github.com/tjluozhongjin/DeveloperHit

About

42034901 Fall2017 Web Service & SOA by Yan LIU @ SSE, TJU

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

50 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

DeveloperHit

iOSSwiftGoNode

After exploring some Web APIs associated with the chosen topic, only a few websites provide friendly APIs, especially when an XML format data response is expected. Therefore we decided to build our own APIs by parsing HTML pages responded from target websites:

  • Github

    Github trending exhibits some potential open source projects, however, there are only APIs for specific repository and user. So we will build an unofficial XML-based backend.

  • V2EX

    V2EX is a community of technology and design. It provides some APIs for getting latest posts.

  • Gank

    Gank.io is a website which provides some interesting frameworks and projects for programmers. Thus, it also pushes some news in software engineering.

  • Zhihu

    Zhihu may be the biggest Q&A community in China. We will write a backend with RESTful API, which providing some development-related topic content.

The frontend will integrate lastest and hot information in a list for users. And I plan to implement it on Web, iOS and Android platform.

Backend

ContentURL
GitHubhttp://115.159.1.222:8000/github
Zhihuhttp://115.159.1.222:3001/topic
V2EXhttps://www.v2ex.com/api/topics/hot.json
Gankhttp://gank.io/api/day/2015/08/07

GitHub

How to Run

go get github.com/zjzsliyang/go-trending
cd DeveloperHit/Backend
go build
./Backend
# to run in the background# nohup ./Backend &

It will run in the 8000 port with the url /github.

Implement

First, to access GitHub data in https://github.com/trending, I reference a web crawler repo and fork it to fix bugs GitHub new trending page via Go. In the backend part, I create a corresponding data structure to store the GitHub data like Developer, Project, Projects. You can find XML Schema in github.xsd.

One shortcoming is that after getting the request from frontend to crawler takes too long, and cache in frontend or distributed crawler is in the plan.

To produce the XML format data, I import encoding/xml, which is called as followings:

funcTrend(res http.ResponseWriter, req*http.Request) {
trend:=trending.NewTrending()
xsiUrl:="http://www.w3.org/2001/XMLSchema-instance"xmlUrl:="https://github.com/zjzsliyang/DeveloperHit/raw/master/Backend/github.xsd"projects, err:=trend.GetProjects(trending.TimeToday, "")
iferr!=nil {
log.Fatal(err)
}
dataProjects:=&Projects{Version: "1", XsiUrl: xsiUrl, XmlUrl: xmlUrl}
for_, project:=rangeprojects {
dataProject:=Project{Name: project.Name, Owner: project.Owner, RepositoryName: project.RepositoryName,
Description: project.Description, Language: project.Language, Stars: project.Stars}
ifproject.URL==nil {
dataProject.URL=""
} else {
dataProject.URL=project.URL.String()
}
ifproject.ContributorURL==nil {
dataProject.ContributorURL=""
} else {
dataProject.ContributorURL=project.ContributorURL.String()
}
for_, contributor:=rangeproject.Contributor {
dataDeveloper:=Developer{ID: contributor.ID, DisplayName: contributor.DisplayName, FullName: contributor.FullName,
URL: contributor.URL.String(), Avatar: contributor.Avatar.String()}
dataProject.Contributor=append(dataProject.Contributor, dataDeveloper)
}
dataProjects.Project=append(dataProjects.Project, dataProject)
}
res.Write([]byte(xml.Header))
output, err:=xml.MarshalIndent(dataProjects, " ", " ")
iferr!=nil {
log.Fatal(err)
}
res.Write(output)
}

Zhihu

Repo: https://github.com/lisirrx/ZhihuApiBackend

How to Run

npm install
npm start

It will run in the 3001 port with the url /topic.

Frontend

Web

Repo: https://github.com/lisirrx/Vue-DeveloperHit

iOS

How to Run

CocoaPods is a dependency manager for Cocoa projects. Run the following command to install the dependency.

cd DeveloperHit/iOS/DeveloperHit
pod install

Screenshot

iOS-GitHubiOS-Zhihu
iOS-V2EXiOS-Gank
iOS-detail_1iOS-detail_2

Implement

iOS part uses MVVM architecture to decouple views and view models. Thus, to satisfy an information aggregation demand, I use table view design widely.

To parse XML data, I call the native XMLParser function in the viewDidLoad stage as follows:

func parser(_ parser:XMLParser, didStartElement elementName:String, namespaceURI:String?, qualifiedName qName:String?, attributes attributeDict:[String:String]=[:]){}
func parser(_ parser:XMLParser, didEndElement elementName:String, namespaceURI:String?, qualifiedName qName:String?){}
func parser(_ parser:XMLParser, foundCharacters string:String){}

The first function will be called when it starts to parse an XML element, I get the XML element node name and init for the data. In the second function, which will be called after parsing the element, so I assign and store the data. The third function is the parse phase function, to reduce the code amount and a better design, I use KVC(Key-Value Coding) which is a mechanism enabled by the NSKeyValueCoding informal protocol that objects adopt to provide indirect access to their properties. When an object is key-value coding compliant, its properties are addressable via string parameters through a concise, uniform messaging interface. This indirect access mechanism supplements the direct access afforded by instance variables and their associated accessor methods. You can find these code here.

To parse JSON data, I use a famous library called Alamofire. Take GankViewController for example:

func requestGank(){Alamofire.request(ServiceBase.GankUrl).response{(response)inletjson=JSON(data: response.data!)forcategoryinself.categorys {vartempGank:[Gank]=[]for(_, subJson):(String,JSON)injson["results"][category]{letgank=Gank(id:subJson["_id"].string!, createAt:subJson["createdAt"].string!, desc:subJson["desc"].string!, publishedAt:subJson["publishedAt"].string!, type:subJson["type"].string!, url:subJson["url"].string!, used:subJson["used"].bool!, who:subJson["who"].string!)
tempGank.append(gank)}self.ganks.append(tempGank)}self.initGankTableView()}}

In the request function, it will callback when it gets the response. I index for the key and store the value.

Android

Repo: https://github.com/tjluozhongjin/DeveloperHit

About

42034901 Fall2017 Web Service & SOA by Yan LIU @ SSE, TJU

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

50 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

DeveloperHit

iOSSwiftGoNode

After exploring some Web APIs associated with the chosen topic, only a few websites provide friendly APIs, especially when an XML format data response is expected. Therefore we decided to build our own APIs by parsing HTML pages responded from target websites:

  • Github

    Github trending exhibits some potential open source projects, however, there are only APIs for specific repository and user. So we will build an unofficial XML-based backend.

  • V2EX

    V2EX is a community of technology and design. It provides some APIs for getting latest posts.

  • Gank

    Gank.io is a website which provides some interesting frameworks and projects for programmers. Thus, it also pushes some news in software engineering.

  • Zhihu

    Zhihu may be the biggest Q&A community in China. We will write a backend with RESTful API, which providing some development-related topic content.

The frontend will integrate lastest and hot information in a list for users. And I plan to implement it on Web, iOS and Android platform.

Backend

ContentURL
GitHubhttp://115.159.1.222:8000/github
Zhihuhttp://115.159.1.222:3001/topic
V2EXhttps://www.v2ex.com/api/topics/hot.json
Gankhttp://gank.io/api/day/2015/08/07

GitHub

How to Run

go get github.com/zjzsliyang/go-trending
cd DeveloperHit/Backend
go build
./Backend
# to run in the background# nohup ./Backend &

It will run in the 8000 port with the url /github.

Implement

First, to access GitHub data in https://github.com/trending, I reference a web crawler repo and fork it to fix bugs GitHub new trending page via Go. In the backend part, I create a corresponding data structure to store the GitHub data like Developer, Project, Projects. You can find XML Schema in github.xsd.

One shortcoming is that after getting the request from frontend to crawler takes too long, and cache in frontend or distributed crawler is in the plan.

To produce the XML format data, I import encoding/xml, which is called as followings:

funcTrend(res http.ResponseWriter, req*http.Request) {
trend:=trending.NewTrending()
xsiUrl:="http://www.w3.org/2001/XMLSchema-instance"xmlUrl:="https://github.com/zjzsliyang/DeveloperHit/raw/master/Backend/github.xsd"projects, err:=trend.GetProjects(trending.TimeToday, "")
iferr!=nil {
log.Fatal(err)
}
dataProjects:=&Projects{Version: "1", XsiUrl: xsiUrl, XmlUrl: xmlUrl}
for_, project:=rangeprojects {
dataProject:=Project{Name: project.Name, Owner: project.Owner, RepositoryName: project.RepositoryName,
Description: project.Description, Language: project.Language, Stars: project.Stars}
ifproject.URL==nil {
dataProject.URL=""
} else {
dataProject.URL=project.URL.String()
}
ifproject.ContributorURL==nil {
dataProject.ContributorURL=""
} else {
dataProject.ContributorURL=project.ContributorURL.String()
}
for_, contributor:=rangeproject.Contributor {
dataDeveloper:=Developer{ID: contributor.ID, DisplayName: contributor.DisplayName, FullName: contributor.FullName,
URL: contributor.URL.String(), Avatar: contributor.Avatar.String()}
dataProject.Contributor=append(dataProject.Contributor, dataDeveloper)
}
dataProjects.Project=append(dataProjects.Project, dataProject)
}
res.Write([]byte(xml.Header))
output, err:=xml.MarshalIndent(dataProjects, " ", " ")
iferr!=nil {
log.Fatal(err)
}
res.Write(output)
}

Zhihu

Repo: https://github.com/lisirrx/ZhihuApiBackend

How to Run

npm install
npm start

It will run in the 3001 port with the url /topic.

Frontend

Web

Repo: https://github.com/lisirrx/Vue-DeveloperHit

iOS

How to Run

CocoaPods is a dependency manager for Cocoa projects. Run the following command to install the dependency.

cd DeveloperHit/iOS/DeveloperHit
pod install

Screenshot

iOS-GitHubiOS-Zhihu
iOS-V2EXiOS-Gank
iOS-detail_1iOS-detail_2

Implement

iOS part uses MVVM architecture to decouple views and view models. Thus, to satisfy an information aggregation demand, I use table view design widely.

To parse XML data, I call the native XMLParser function in the viewDidLoad stage as follows:

func parser(_ parser:XMLParser, didStartElement elementName:String, namespaceURI:String?, qualifiedName qName:String?, attributes attributeDict:[String:String]=[:]){}
func parser(_ parser:XMLParser, didEndElement elementName:String, namespaceURI:String?, qualifiedName qName:String?){}
func parser(_ parser:XMLParser, foundCharacters string:String){}

The first function will be called when it starts to parse an XML element, I get the XML element node name and init for the data. In the second function, which will be called after parsing the element, so I assign and store the data. The third function is the parse phase function, to reduce the code amount and a better design, I use KVC(Key-Value Coding) which is a mechanism enabled by the NSKeyValueCoding informal protocol that objects adopt to provide indirect access to their properties. When an object is key-value coding compliant, its properties are addressable via string parameters through a concise, uniform messaging interface. This indirect access mechanism supplements the direct access afforded by instance variables and their associated accessor methods. You can find these code here.

To parse JSON data, I use a famous library called Alamofire. Take GankViewController for example:

func requestGank(){Alamofire.request(ServiceBase.GankUrl).response{(response)inletjson=JSON(data: response.data!)forcategoryinself.categorys {vartempGank:[Gank]=[]for(_, subJson):(String,JSON)injson["results"][category]{letgank=Gank(id:subJson["_id"].string!, createAt:subJson["createdAt"].string!, desc:subJson["desc"].string!, publishedAt:subJson["publishedAt"].string!, type:subJson["type"].string!, url:subJson["url"].string!, used:subJson["used"].bool!, who:subJson["who"].string!)
tempGank.append(gank)}self.ganks.append(tempGank)}self.initGankTableView()}}

In the request function, it will callback when it gets the response. I index for the key and store the value.

Android

Repo: https://github.com/tjluozhongjin/DeveloperHit

About

42034901 Fall2017 Web Service & SOA by Yan LIU @ SSE, TJU

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

50 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

DeveloperHit

iOSSwiftGoNode

After exploring some Web APIs associated with the chosen topic, only a few websites provide friendly APIs, especially when an XML format data response is expected. Therefore we decided to build our own APIs by parsing HTML pages responded from target websites:

  • Github

    Github trending exhibits some potential open source projects, however, there are only APIs for specific repository and user. So we will build an unofficial XML-based backend.

  • V2EX

    V2EX is a community of technology and design. It provides some APIs for getting latest posts.

  • Gank

    Gank.io is a website which provides some interesting frameworks and projects for programmers. Thus, it also pushes some news in software engineering.

  • Zhihu

    Zhihu may be the biggest Q&A community in China. We will write a backend with RESTful API, which providing some development-related topic content.

The frontend will integrate lastest and hot information in a list for users. And I plan to implement it on Web, iOS and Android platform.

Backend

ContentURL
GitHubhttp://115.159.1.222:8000/github
Zhihuhttp://115.159.1.222:3001/topic
V2EXhttps://www.v2ex.com/api/topics/hot.json
Gankhttp://gank.io/api/day/2015/08/07

GitHub

How to Run

go get github.com/zjzsliyang/go-trending
cd DeveloperHit/Backend
go build
./Backend
# to run in the background# nohup ./Backend &

It will run in the 8000 port with the url /github.

Implement

First, to access GitHub data in https://github.com/trending, I reference a web crawler repo and fork it to fix bugs GitHub new trending page via Go. In the backend part, I create a corresponding data structure to store the GitHub data like Developer, Project, Projects. You can find XML Schema in github.xsd.

One shortcoming is that after getting the request from frontend to crawler takes too long, and cache in frontend or distributed crawler is in the plan.

To produce the XML format data, I import encoding/xml, which is called as followings:

funcTrend(res http.ResponseWriter, req*http.Request) {
trend:=trending.NewTrending()
xsiUrl:="http://www.w3.org/2001/XMLSchema-instance"xmlUrl:="https://github.com/zjzsliyang/DeveloperHit/raw/master/Backend/github.xsd"projects, err:=trend.GetProjects(trending.TimeToday, "")
iferr!=nil {
log.Fatal(err)
}
dataProjects:=&Projects{Version: "1", XsiUrl: xsiUrl, XmlUrl: xmlUrl}
for_, project:=rangeprojects {
dataProject:=Project{Name: project.Name, Owner: project.Owner, RepositoryName: project.RepositoryName,
Description: project.Description, Language: project.Language, Stars: project.Stars}
ifproject.URL==nil {
dataProject.URL=""
} else {
dataProject.URL=project.URL.String()
}
ifproject.ContributorURL==nil {
dataProject.ContributorURL=""
} else {
dataProject.ContributorURL=project.ContributorURL.String()
}
for_, contributor:=rangeproject.Contributor {
dataDeveloper:=Developer{ID: contributor.ID, DisplayName: contributor.DisplayName, FullName: contributor.FullName,
URL: contributor.URL.String(), Avatar: contributor.Avatar.String()}
dataProject.Contributor=append(dataProject.Contributor, dataDeveloper)
}
dataProjects.Project=append(dataProjects.Project, dataProject)
}
res.Write([]byte(xml.Header))
output, err:=xml.MarshalIndent(dataProjects, " ", " ")
iferr!=nil {
log.Fatal(err)
}
res.Write(output)
}

Zhihu

Repo: https://github.com/lisirrx/ZhihuApiBackend

How to Run

npm install
npm start

It will run in the 3001 port with the url /topic.

Frontend

Web

Repo: https://github.com/lisirrx/Vue-DeveloperHit

iOS

How to Run

CocoaPods is a dependency manager for Cocoa projects. Run the following command to install the dependency.

cd DeveloperHit/iOS/DeveloperHit
pod install

Screenshot

iOS-GitHubiOS-Zhihu
iOS-V2EXiOS-Gank
iOS-detail_1iOS-detail_2

Implement

iOS part uses MVVM architecture to decouple views and view models. Thus, to satisfy an information aggregation demand, I use table view design widely.

To parse XML data, I call the native XMLParser function in the viewDidLoad stage as follows:

func parser(_ parser:XMLParser, didStartElement elementName:String, namespaceURI:String?, qualifiedName qName:String?, attributes attributeDict:[String:String]=[:]){}
func parser(_ parser:XMLParser, didEndElement elementName:String, namespaceURI:String?, qualifiedName qName:String?){}
func parser(_ parser:XMLParser, foundCharacters string:String){}

The first function will be called when it starts to parse an XML element, I get the XML element node name and init for the data. In the second function, which will be called after parsing the element, so I assign and store the data. The third function is the parse phase function, to reduce the code amount and a better design, I use KVC(Key-Value Coding) which is a mechanism enabled by the NSKeyValueCoding informal protocol that objects adopt to provide indirect access to their properties. When an object is key-value coding compliant, its properties are addressable via string parameters through a concise, uniform messaging interface. This indirect access mechanism supplements the direct access afforded by instance variables and their associated accessor methods. You can find these code here.

To parse JSON data, I use a famous library called Alamofire. Take GankViewController for example:

func requestGank(){Alamofire.request(ServiceBase.GankUrl).response{(response)inletjson=JSON(data: response.data!)forcategoryinself.categorys {vartempGank:[Gank]=[]for(_, subJson):(String,JSON)injson["results"][category]{letgank=Gank(id:subJson["_id"].string!, createAt:subJson["createdAt"].string!, desc:subJson["desc"].string!, publishedAt:subJson["publishedAt"].string!, type:subJson["type"].string!, url:subJson["url"].string!, used:subJson["used"].bool!, who:subJson["who"].string!)
tempGank.append(gank)}self.ganks.append(tempGank)}self.initGankTableView()}}

In the request function, it will callback when it gets the response. I index for the key and store the value.

Android

Repo: https://github.com/tjluozhongjin/DeveloperHit

About

42034901 Fall2017 Web Service & SOA by Yan LIU @ SSE, TJU

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

50 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

DeveloperHit

iOSSwiftGoNode

After exploring some Web APIs associated with the chosen topic, only a few websites provide friendly APIs, especially when an XML format data response is expected. Therefore we decided to build our own APIs by parsing HTML pages responded from target websites:

  • Github

    Github trending exhibits some potential open source projects, however, there are only APIs for specific repository and user. So we will build an unofficial XML-based backend.

  • V2EX

    V2EX is a community of technology and design. It provides some APIs for getting latest posts.

  • Gank

    Gank.io is a website which provides some interesting frameworks and projects for programmers. Thus, it also pushes some news in software engineering.

  • Zhihu

    Zhihu may be the biggest Q&A community in China. We will write a backend with RESTful API, which providing some development-related topic content.

The frontend will integrate lastest and hot information in a list for users. And I plan to implement it on Web, iOS and Android platform.

Backend

ContentURL
GitHubhttp://115.159.1.222:8000/github
Zhihuhttp://115.159.1.222:3001/topic
V2EXhttps://www.v2ex.com/api/topics/hot.json
Gankhttp://gank.io/api/day/2015/08/07

GitHub

How to Run

go get github.com/zjzsliyang/go-trending
cd DeveloperHit/Backend
go build
./Backend
# to run in the background# nohup ./Backend &

It will run in the 8000 port with the url /github.

Implement

First, to access GitHub data in https://github.com/trending, I reference a web crawler repo and fork it to fix bugs GitHub new trending page via Go. In the backend part, I create a corresponding data structure to store the GitHub data like Developer, Project, Projects. You can find XML Schema in github.xsd.

One shortcoming is that after getting the request from frontend to crawler takes too long, and cache in frontend or distributed crawler is in the plan.

To produce the XML format data, I import encoding/xml, which is called as followings:

funcTrend(res http.ResponseWriter, req*http.Request) {
trend:=trending.NewTrending()
xsiUrl:="http://www.w3.org/2001/XMLSchema-instance"xmlUrl:="https://github.com/zjzsliyang/DeveloperHit/raw/master/Backend/github.xsd"projects, err:=trend.GetProjects(trending.TimeToday, "")
iferr!=nil {
log.Fatal(err)
}
dataProjects:=&Projects{Version: "1", XsiUrl: xsiUrl, XmlUrl: xmlUrl}
for_, project:=rangeprojects {
dataProject:=Project{Name: project.Name, Owner: project.Owner, RepositoryName: project.RepositoryName,
Description: project.Description, Language: project.Language, Stars: project.Stars}
ifproject.URL==nil {
dataProject.URL=""
} else {
dataProject.URL=project.URL.String()
}
ifproject.ContributorURL==nil {
dataProject.ContributorURL=""
} else {
dataProject.ContributorURL=project.ContributorURL.String()
}
for_, contributor:=rangeproject.Contributor {
dataDeveloper:=Developer{ID: contributor.ID, DisplayName: contributor.DisplayName, FullName: contributor.FullName,
URL: contributor.URL.String(), Avatar: contributor.Avatar.String()}
dataProject.Contributor=append(dataProject.Contributor, dataDeveloper)
}
dataProjects.Project=append(dataProjects.Project, dataProject)
}
res.Write([]byte(xml.Header))
output, err:=xml.MarshalIndent(dataProjects, " ", " ")
iferr!=nil {
log.Fatal(err)
}
res.Write(output)
}

Zhihu

Repo: https://github.com/lisirrx/ZhihuApiBackend

How to Run

npm install
npm start

It will run in the 3001 port with the url /topic.

Frontend

Web

Repo: https://github.com/lisirrx/Vue-DeveloperHit

iOS

How to Run

CocoaPods is a dependency manager for Cocoa projects. Run the following command to install the dependency.

cd DeveloperHit/iOS/DeveloperHit
pod install

Screenshot

iOS-GitHubiOS-Zhihu
iOS-V2EXiOS-Gank
iOS-detail_1iOS-detail_2

Implement

iOS part uses MVVM architecture to decouple views and view models. Thus, to satisfy an information aggregation demand, I use table view design widely.

To parse XML data, I call the native XMLParser function in the viewDidLoad stage as follows:

func parser(_ parser:XMLParser, didStartElement elementName:String, namespaceURI:String?, qualifiedName qName:String?, attributes attributeDict:[String:String]=[:]){}
func parser(_ parser:XMLParser, didEndElement elementName:String, namespaceURI:String?, qualifiedName qName:String?){}
func parser(_ parser:XMLParser, foundCharacters string:String){}

The first function will be called when it starts to parse an XML element, I get the XML element node name and init for the data. In the second function, which will be called after parsing the element, so I assign and store the data. The third function is the parse phase function, to reduce the code amount and a better design, I use KVC(Key-Value Coding) which is a mechanism enabled by the NSKeyValueCoding informal protocol that objects adopt to provide indirect access to their properties. When an object is key-value coding compliant, its properties are addressable via string parameters through a concise, uniform messaging interface. This indirect access mechanism supplements the direct access afforded by instance variables and their associated accessor methods. You can find these code here.

To parse JSON data, I use a famous library called Alamofire. Take GankViewController for example:

func requestGank(){Alamofire.request(ServiceBase.GankUrl).response{(response)inletjson=JSON(data: response.data!)forcategoryinself.categorys {vartempGank:[Gank]=[]for(_, subJson):(String,JSON)injson["results"][category]{letgank=Gank(id:subJson["_id"].string!, createAt:subJson["createdAt"].string!, desc:subJson["desc"].string!, publishedAt:subJson["publishedAt"].string!, type:subJson["type"].string!, url:subJson["url"].string!, used:subJson["used"].bool!, who:subJson["who"].string!)
tempGank.append(gank)}self.ganks.append(tempGank)}self.initGankTableView()}}

In the request function, it will callback when it gets the response. I index for the key and store the value.

Android

Repo: https://github.com/tjluozhongjin/DeveloperHit

About

42034901 Fall2017 Web Service & SOA by Yan LIU @ SSE, TJU

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

50 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

DeveloperHit

iOSSwiftGoNode

After exploring some Web APIs associated with the chosen topic, only a few websites provide friendly APIs, especially when an XML format data response is expected. Therefore we decided to build our own APIs by parsing HTML pages responded from target websites:

  • Github

    Github trending exhibits some potential open source projects, however, there are only APIs for specific repository and user. So we will build an unofficial XML-based backend.

  • V2EX

    V2EX is a community of technology and design. It provides some APIs for getting latest posts.

  • Gank

    Gank.io is a website which provides some interesting frameworks and projects for programmers. Thus, it also pushes some news in software engineering.

  • Zhihu

    Zhihu may be the biggest Q&A community in China. We will write a backend with RESTful API, which providing some development-related topic content.

The frontend will integrate lastest and hot information in a list for users. And I plan to implement it on Web, iOS and Android platform.

Backend

ContentURL
GitHubhttp://115.159.1.222:8000/github
Zhihuhttp://115.159.1.222:3001/topic
V2EXhttps://www.v2ex.com/api/topics/hot.json
Gankhttp://gank.io/api/day/2015/08/07

GitHub

How to Run

go get github.com/zjzsliyang/go-trending
cd DeveloperHit/Backend
go build
./Backend
# to run in the background# nohup ./Backend &

It will run in the 8000 port with the url /github.

Implement

First, to access GitHub data in https://github.com/trending, I reference a web crawler repo and fork it to fix bugs GitHub new trending page via Go. In the backend part, I create a corresponding data structure to store the GitHub data like Developer, Project, Projects. You can find XML Schema in github.xsd.

One shortcoming is that after getting the request from frontend to crawler takes too long, and cache in frontend or distributed crawler is in the plan.

To produce the XML format data, I import encoding/xml, which is called as followings:

funcTrend(res http.ResponseWriter, req*http.Request) {
trend:=trending.NewTrending()
xsiUrl:="http://www.w3.org/2001/XMLSchema-instance"xmlUrl:="https://github.com/zjzsliyang/DeveloperHit/raw/master/Backend/github.xsd"projects, err:=trend.GetProjects(trending.TimeToday, "")
iferr!=nil {
log.Fatal(err)
}
dataProjects:=&Projects{Version: "1", XsiUrl: xsiUrl, XmlUrl: xmlUrl}
for_, project:=rangeprojects {
dataProject:=Project{Name: project.Name, Owner: project.Owner, RepositoryName: project.RepositoryName,
Description: project.Description, Language: project.Language, Stars: project.Stars}
ifproject.URL==nil {
dataProject.URL=""
} else {
dataProject.URL=project.URL.String()
}
ifproject.ContributorURL==nil {
dataProject.ContributorURL=""
} else {
dataProject.ContributorURL=project.ContributorURL.String()
}
for_, contributor:=rangeproject.Contributor {
dataDeveloper:=Developer{ID: contributor.ID, DisplayName: contributor.DisplayName, FullName: contributor.FullName,
URL: contributor.URL.String(), Avatar: contributor.Avatar.String()}
dataProject.Contributor=append(dataProject.Contributor, dataDeveloper)
}
dataProjects.Project=append(dataProjects.Project, dataProject)
}
res.Write([]byte(xml.Header))
output, err:=xml.MarshalIndent(dataProjects, " ", " ")
iferr!=nil {
log.Fatal(err)
}
res.Write(output)
}

Zhihu

Repo: https://github.com/lisirrx/ZhihuApiBackend

How to Run

npm install
npm start

It will run in the 3001 port with the url /topic.

Frontend

Web

Repo: https://github.com/lisirrx/Vue-DeveloperHit

iOS

How to Run

CocoaPods is a dependency manager for Cocoa projects. Run the following command to install the dependency.

cd DeveloperHit/iOS/DeveloperHit
pod install

Screenshot

iOS-GitHubiOS-Zhihu
iOS-V2EXiOS-Gank
iOS-detail_1iOS-detail_2

Implement

iOS part uses MVVM architecture to decouple views and view models. Thus, to satisfy an information aggregation demand, I use table view design widely.

To parse XML data, I call the native XMLParser function in the viewDidLoad stage as follows:

func parser(_ parser:XMLParser, didStartElement elementName:String, namespaceURI:String?, qualifiedName qName:String?, attributes attributeDict:[String:String]=[:]){}
func parser(_ parser:XMLParser, didEndElement elementName:String, namespaceURI:String?, qualifiedName qName:String?){}
func parser(_ parser:XMLParser, foundCharacters string:String){}

The first function will be called when it starts to parse an XML element, I get the XML element node name and init for the data. In the second function, which will be called after parsing the element, so I assign and store the data. The third function is the parse phase function, to reduce the code amount and a better design, I use KVC(Key-Value Coding) which is a mechanism enabled by the NSKeyValueCoding informal protocol that objects adopt to provide indirect access to their properties. When an object is key-value coding compliant, its properties are addressable via string parameters through a concise, uniform messaging interface. This indirect access mechanism supplements the direct access afforded by instance variables and their associated accessor methods. You can find these code here.

To parse JSON data, I use a famous library called Alamofire. Take GankViewController for example:

func requestGank(){Alamofire.request(ServiceBase.GankUrl).response{(response)inletjson=JSON(data: response.data!)forcategoryinself.categorys {vartempGank:[Gank]=[]for(_, subJson):(String,JSON)injson["results"][category]{letgank=Gank(id:subJson["_id"].string!, createAt:subJson["createdAt"].string!, desc:subJson["desc"].string!, publishedAt:subJson["publishedAt"].string!, type:subJson["type"].string!, url:subJson["url"].string!, used:subJson["used"].bool!, who:subJson["who"].string!)
tempGank.append(gank)}self.ganks.append(tempGank)}self.initGankTableView()}}

In the request function, it will callback when it gets the response. I index for the key and store the value.

Android

Repo: https://github.com/tjluozhongjin/DeveloperHit

About

42034901 Fall2017 Web Service & SOA by Yan LIU @ SSE, TJU

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

50 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

DeveloperHit

iOSSwiftGoNode

After exploring some Web APIs associated with the chosen topic, only a few websites provide friendly APIs, especially when an XML format data response is expected. Therefore we decided to build our own APIs by parsing HTML pages responded from target websites:

  • Github

    Github trending exhibits some potential open source projects, however, there are only APIs for specific repository and user. So we will build an unofficial XML-based backend.

  • V2EX

    V2EX is a community of technology and design. It provides some APIs for getting latest posts.

  • Gank

    Gank.io is a website which provides some interesting frameworks and projects for programmers. Thus, it also pushes some news in software engineering.

  • Zhihu

    Zhihu may be the biggest Q&A community in China. We will write a backend with RESTful API, which providing some development-related topic content.

The frontend will integrate lastest and hot information in a list for users. And I plan to implement it on Web, iOS and Android platform.

Backend

ContentURL
GitHubhttp://115.159.1.222:8000/github
Zhihuhttp://115.159.1.222:3001/topic
V2EXhttps://www.v2ex.com/api/topics/hot.json
Gankhttp://gank.io/api/day/2015/08/07

GitHub

How to Run

go get github.com/zjzsliyang/go-trending
cd DeveloperHit/Backend
go build
./Backend
# to run in the background# nohup ./Backend &

It will run in the 8000 port with the url /github.

Implement

First, to access GitHub data in https://github.com/trending, I reference a web crawler repo and fork it to fix bugs GitHub new trending page via Go. In the backend part, I create a corresponding data structure to store the GitHub data like Developer, Project, Projects. You can find XML Schema in github.xsd.

One shortcoming is that after getting the request from frontend to crawler takes too long, and cache in frontend or distributed crawler is in the plan.

To produce the XML format data, I import encoding/xml, which is called as followings:

funcTrend(res http.ResponseWriter, req*http.Request) {
trend:=trending.NewTrending()
xsiUrl:="http://www.w3.org/2001/XMLSchema-instance"xmlUrl:="https://github.com/zjzsliyang/DeveloperHit/raw/master/Backend/github.xsd"projects, err:=trend.GetProjects(trending.TimeToday, "")
iferr!=nil {
log.Fatal(err)
}
dataProjects:=&Projects{Version: "1", XsiUrl: xsiUrl, XmlUrl: xmlUrl}
for_, project:=rangeprojects {
dataProject:=Project{Name: project.Name, Owner: project.Owner, RepositoryName: project.RepositoryName,
Description: project.Description, Language: project.Language, Stars: project.Stars}
ifproject.URL==nil {
dataProject.URL=""
} else {
dataProject.URL=project.URL.String()
}
ifproject.ContributorURL==nil {
dataProject.ContributorURL=""
} else {
dataProject.ContributorURL=project.ContributorURL.String()
}
for_, contributor:=rangeproject.Contributor {
dataDeveloper:=Developer{ID: contributor.ID, DisplayName: contributor.DisplayName, FullName: contributor.FullName,
URL: contributor.URL.String(), Avatar: contributor.Avatar.String()}
dataProject.Contributor=append(dataProject.Contributor, dataDeveloper)
}
dataProjects.Project=append(dataProjects.Project, dataProject)
}
res.Write([]byte(xml.Header))
output, err:=xml.MarshalIndent(dataProjects, " ", " ")
iferr!=nil {
log.Fatal(err)
}
res.Write(output)
}

Zhihu

Repo: https://github.com/lisirrx/ZhihuApiBackend

How to Run

npm install
npm start

It will run in the 3001 port with the url /topic.

Frontend

Web

Repo: https://github.com/lisirrx/Vue-DeveloperHit

iOS

How to Run

CocoaPods is a dependency manager for Cocoa projects. Run the following command to install the dependency.

cd DeveloperHit/iOS/DeveloperHit
pod install

Screenshot

iOS-GitHubiOS-Zhihu
iOS-V2EXiOS-Gank
iOS-detail_1iOS-detail_2

Implement

iOS part uses MVVM architecture to decouple views and view models. Thus, to satisfy an information aggregation demand, I use table view design widely.

To parse XML data, I call the native XMLParser function in the viewDidLoad stage as follows:

func parser(_ parser:XMLParser, didStartElement elementName:String, namespaceURI:String?, qualifiedName qName:String?, attributes attributeDict:[String:String]=[:]){}
func parser(_ parser:XMLParser, didEndElement elementName:String, namespaceURI:String?, qualifiedName qName:String?){}
func parser(_ parser:XMLParser, foundCharacters string:String){}

The first function will be called when it starts to parse an XML element, I get the XML element node name and init for the data. In the second function, which will be called after parsing the element, so I assign and store the data. The third function is the parse phase function, to reduce the code amount and a better design, I use KVC(Key-Value Coding) which is a mechanism enabled by the NSKeyValueCoding informal protocol that objects adopt to provide indirect access to their properties. When an object is key-value coding compliant, its properties are addressable via string parameters through a concise, uniform messaging interface. This indirect access mechanism supplements the direct access afforded by instance variables and their associated accessor methods. You can find these code here.

To parse JSON data, I use a famous library called Alamofire. Take GankViewController for example:

func requestGank(){Alamofire.request(ServiceBase.GankUrl).response{(response)inletjson=JSON(data: response.data!)forcategoryinself.categorys {vartempGank:[Gank]=[]for(_, subJson):(String,JSON)injson["results"][category]{letgank=Gank(id:subJson["_id"].string!, createAt:subJson["createdAt"].string!, desc:subJson["desc"].string!, publishedAt:subJson["publishedAt"].string!, type:subJson["type"].string!, url:subJson["url"].string!, used:subJson["used"].bool!, who:subJson["who"].string!)
tempGank.append(gank)}self.ganks.append(tempGank)}self.initGankTableView()}}

In the request function, it will callback when it gets the response. I index for the key and store the value.

Android

Repo: https://github.com/tjluozhongjin/DeveloperHit

About

42034901 Fall2017 Web Service & SOA by Yan LIU @ SSE, TJU

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

50 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

DeveloperHit

iOSSwiftGoNode

After exploring some Web APIs associated with the chosen topic, only a few websites provide friendly APIs, especially when an XML format data response is expected. Therefore we decided to build our own APIs by parsing HTML pages responded from target websites:

  • Github

    Github trending exhibits some potential open source projects, however, there are only APIs for specific repository and user. So we will build an unofficial XML-based backend.

  • V2EX

    V2EX is a community of technology and design. It provides some APIs for getting latest posts.

  • Gank

    Gank.io is a website which provides some interesting frameworks and projects for programmers. Thus, it also pushes some news in software engineering.

  • Zhihu

    Zhihu may be the biggest Q&A community in China. We will write a backend with RESTful API, which providing some development-related topic content.

The frontend will integrate lastest and hot information in a list for users. And I plan to implement it on Web, iOS and Android platform.

Backend

ContentURL
GitHubhttp://115.159.1.222:8000/github
Zhihuhttp://115.159.1.222:3001/topic
V2EXhttps://www.v2ex.com/api/topics/hot.json
Gankhttp://gank.io/api/day/2015/08/07

GitHub

How to Run

go get github.com/zjzsliyang/go-trending
cd DeveloperHit/Backend
go build
./Backend
# to run in the background# nohup ./Backend &

It will run in the 8000 port with the url /github.

Implement

First, to access GitHub data in https://github.com/trending, I reference a web crawler repo and fork it to fix bugs GitHub new trending page via Go. In the backend part, I create a corresponding data structure to store the GitHub data like Developer, Project, Projects. You can find XML Schema in github.xsd.

One shortcoming is that after getting the request from frontend to crawler takes too long, and cache in frontend or distributed crawler is in the plan.

To produce the XML format data, I import encoding/xml, which is called as followings:

funcTrend(res http.ResponseWriter, req*http.Request) {
trend:=trending.NewTrending()
xsiUrl:="http://www.w3.org/2001/XMLSchema-instance"xmlUrl:="https://github.com/zjzsliyang/DeveloperHit/raw/master/Backend/github.xsd"projects, err:=trend.GetProjects(trending.TimeToday, "")
iferr!=nil {
log.Fatal(err)
}
dataProjects:=&Projects{Version: "1", XsiUrl: xsiUrl, XmlUrl: xmlUrl}
for_, project:=rangeprojects {
dataProject:=Project{Name: project.Name, Owner: project.Owner, RepositoryName: project.RepositoryName,
Description: project.Description, Language: project.Language, Stars: project.Stars}
ifproject.URL==nil {
dataProject.URL=""
} else {
dataProject.URL=project.URL.String()
}
ifproject.ContributorURL==nil {
dataProject.ContributorURL=""
} else {
dataProject.ContributorURL=project.ContributorURL.String()
}
for_, contributor:=rangeproject.Contributor {
dataDeveloper:=Developer{ID: contributor.ID, DisplayName: contributor.DisplayName, FullName: contributor.FullName,
URL: contributor.URL.String(), Avatar: contributor.Avatar.String()}
dataProject.Contributor=append(dataProject.Contributor, dataDeveloper)
}
dataProjects.Project=append(dataProjects.Project, dataProject)
}
res.Write([]byte(xml.Header))
output, err:=xml.MarshalIndent(dataProjects, " ", " ")
iferr!=nil {
log.Fatal(err)
}
res.Write(output)
}

Zhihu

Repo: https://github.com/lisirrx/ZhihuApiBackend

How to Run

npm install
npm start

It will run in the 3001 port with the url /topic.

Frontend

Web

Repo: https://github.com/lisirrx/Vue-DeveloperHit

iOS

How to Run

CocoaPods is a dependency manager for Cocoa projects. Run the following command to install the dependency.

cd DeveloperHit/iOS/DeveloperHit
pod install

Screenshot

iOS-GitHubiOS-Zhihu
iOS-V2EXiOS-Gank
iOS-detail_1iOS-detail_2

Implement

iOS part uses MVVM architecture to decouple views and view models. Thus, to satisfy an information aggregation demand, I use table view design widely.

To parse XML data, I call the native XMLParser function in the viewDidLoad stage as follows:

func parser(_ parser:XMLParser, didStartElement elementName:String, namespaceURI:String?, qualifiedName qName:String?, attributes attributeDict:[String:String]=[:]){}
func parser(_ parser:XMLParser, didEndElement elementName:String, namespaceURI:String?, qualifiedName qName:String?){}
func parser(_ parser:XMLParser, foundCharacters string:String){}

The first function will be called when it starts to parse an XML element, I get the XML element node name and init for the data. In the second function, which will be called after parsing the element, so I assign and store the data. The third function is the parse phase function, to reduce the code amount and a better design, I use KVC(Key-Value Coding) which is a mechanism enabled by the NSKeyValueCoding informal protocol that objects adopt to provide indirect access to their properties. When an object is key-value coding compliant, its properties are addressable via string parameters through a concise, uniform messaging interface. This indirect access mechanism supplements the direct access afforded by instance variables and their associated accessor methods. You can find these code here.

To parse JSON data, I use a famous library called Alamofire. Take GankViewController for example:

func requestGank(){Alamofire.request(ServiceBase.GankUrl).response{(response)inletjson=JSON(data: response.data!)forcategoryinself.categorys {vartempGank:[Gank]=[]for(_, subJson):(String,JSON)injson["results"][category]{letgank=Gank(id:subJson["_id"].string!, createAt:subJson["createdAt"].string!, desc:subJson["desc"].string!, publishedAt:subJson["publishedAt"].string!, type:subJson["type"].string!, url:subJson["url"].string!, used:subJson["used"].bool!, who:subJson["who"].string!)
tempGank.append(gank)}self.ganks.append(tempGank)}self.initGankTableView()}}

In the request function, it will callback when it gets the response. I index for the key and store the value.

Android

Repo: https://github.com/tjluozhongjin/DeveloperHit

About

42034901 Fall2017 Web Service & SOA by Yan LIU @ SSE, TJU

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages