├── .gitignore
├── LICENSE
├── README.md
├── email_lookup.md
├── examples
├── ApiExample.cpp
│ ├── bin
│ │ └── .gitkeep
│ ├── build
│ │ └── vs2005
│ │ │ ├── OhlohApiExample.sln
│ │ │ └── OhlohApiExample.vcproj
│ ├── compile.sh
│ ├── include
│ │ ├── HTTPDownload.h
│ │ ├── TCPSocket.h
│ │ ├── main.h
│ │ ├── md5.h
│ │ ├── tinystr.h
│ │ └── tinyxml.h
│ ├── src
│ │ ├── ApiExample
│ │ ├── HTTPDownload.cpp
│ │ ├── TCPSocket.cpp
│ │ ├── main.cpp
│ │ ├── makefile
│ │ ├── md5.cpp
│ │ ├── tinystr.cpp
│ │ ├── tinyxml.cpp
│ │ ├── tinyxmlerror.cpp
│ │ └── tinyxmlparser.cpp
│ └── temp.xml
├── ApiExample.java
├── README.md
├── account_sample.pl
├── account_sample.py
├── account_sample.rb
├── account_sample.sh
└── oauth2
│ ├── README.md
│ └── ohloh_oauth2_sinatra.rb
└── reference
├── account.md
├── activity_fact.md
├── affiliated_committers.md
├── analysis.md
├── code_location.md
├── contributor_fact.md
├── contributor_language_fact.md
├── enlistment.md
├── factoid.md
├── kudo.md
├── kudo_score.md
├── language.md
├── organization-collection.md
├── organization.md
├── outside_committers.md
├── outside_projects.md
├── portfolio_projects.md
├── position.md
├── project.md
├── size_fact.md
├── stack.md
└── stack_entry.md
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2025 Black Duck Software, Inc. and its contributors.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Open Hub API Documentation
2 |
3 | ## Welcome
4 |
5 | The Open Hub API is a free, REST-based programming interface to the Black Duck Open Hub open source directory. You can use the Open Hub API to create your own applications and web services based on Open Hub data.
6 |
7 | ## Getting Help
8 |
9 | This page contains important summary information to help you get started. In-depth online documentation is available, linked by the table of contents below.
10 |
11 | Some sample code can be found on the [Examples](examples/) page. For questions not covered in the documenation, the [Open Hub Technical Issues Help](https://community.blackduck.com/s/topic/0TO2H000000gHS1WAM/black-duck-open-hub-help) can provide additional help.
12 |
13 | Send bug reports to info@openhub.net.
14 |
15 | ## Table of Contents
16 | + [Lookup By Email](email_lookup.md)
17 | + [Using OAuth with the Open Hub API](examples/oauth2)
18 | + [Examples](examples/)
19 | + Open Hub API Reference
20 | - [Account](reference/account.md)
21 | - [Account News](reference/news.md)
22 | - [ActivityFact](reference/activity_fact.md)
23 | - [AffiliatedCommitters](reference/affiliated_committers.md)
24 | - [Analysis](reference/analysis.md)
25 | - [ContributorFact](reference/contributor_fact.md)
26 | - [ContributorLanguageFact](reference/contributor_language_fact.md)
27 | - [Enlistment](reference/enlistment.md)
28 | - [Factoid](reference/factoid.md)
29 | - [Kudo](reference/kudo.md)
30 | - [KudoScore](reference/kudo_score.md)
31 | - [Language](reference/language.md)
32 | - [Message](reference/message.md)
33 | - [Organization](reference/organization.md)
34 | - [Organization-collection](reference/organization-collection.md)
35 | - [OutsideCommitters](reference/outside_committers.md)
36 | - [OutsideProjects](reference/outside_projects.md)
37 | - [PortfolioProjects](reference/portfolio_projects.md)
38 | - [Position](reference/position.md)
39 | - [Project](reference/project.md)
40 | - [Repository](reference/repository.md)
41 | - [SizeFact](reference/size_fact.md)
42 | - [Stack](reference/stack.md)
43 | - [StackEntry](reference/stack_entry.md)
44 | + [API Use Agreement](http://blog.openhub.net/terms-2/)
45 | + [Apply for an API Key](https://www.openhub.net/accounts/me/api_keys/new)
46 | + [API Key Status](https://www.openhub.net/accounts/me/api_keys)
47 |
48 | ## Terms of Use
49 |
50 | The Open Hub API has some restrictions. Please review the complete [Terms of Use](https://community.blackduck.com/s/article/Black-Duck-Open-Hub-API-Use-Agreement) before you begin.
51 |
52 | We ask that you cite Open Hub in publications that use our data. Please include a link to https://www.openhub.net on your web pages.
53 |
54 | Our terms require you to provide a link back to our site. While you’re free to use any method you’d prefer, we’ve provided this small button for your convenience: 
55 |
56 | We recommend linking to our home page. The following html will link the small badge to our home page:
57 |
58 | ```html
59 |
60 | ```
61 |
62 | ## API Key
63 |
64 | Before you can access the Open Hub API, you must [register your application](https://www.openhub.net/accounts/me/api_keys/new) and obtain an API key. Bandwidth will initially be limited to 1,000 requests per API key per day.
65 |
66 | An API Key should be unique to each application that accesses the Open Hub API. You can register up to five applications.
67 |
68 | It is important not to share API keys. In order to access or modify account data, your application must be granted permission by an individual Open Hub account holder. This permission is granted on a per-key basis.
69 |
70 | You can [register a new application](https://www.openhub.net/accounts/me/api_keys/new) or [view the status](https://www.openhub.net/accounts/me/api_keys) of your existing applications online.
71 |
72 | If you have special requirements for additional keys, or if you are interested in building a large-scale application, please contact us at info@openhub.net.
73 |
74 | ## OAuth Impersonation
75 |
76 | The standard Open Hub API allows read-only access to Open Hub data.
77 |
78 | Using OAuth, you can impersonate an Open Hub account while accessing the Open Hub API. This enables you to write to the Open Hub database, and also to access or modify private account information. You must first be granted permission to do this by an Open Hub account holder.
79 |
80 | You can read more at [Using OAuth with the Open Hub API](examples/oauth2#using-oauth-20).
81 |
82 | ## Forming a Request
83 |
84 | The Open Hub API returns XML-formatted data in response to HTTP GET requests.
85 |
86 | The design concept is that for each web page on Open Hub, there may be an equivalent XML-formatted version of the page. Most pages on the Black Duck Open Hub have an XML representation.
87 |
88 | You must do three things to receive an XML-formatted response:
89 |
90 | 1. Append a `.xml` extension to the basic URL. For example, instead of `https://www.openhub.net/p/1`, which returns an HTML page, you would request `https://www.openhub.net/p/1.xml`.
91 | 2. Provide your API Key as an HTTP parameter. Your request will be forbidden without a valid `api_key`.
92 |
93 | For example, to view the project with ID=1 as XML, using an example API key, the complete URL would be:
94 |
95 | ```
96 | https://www.openhub.net/p/1.xml?api_key=01234567890123456789
97 | ```
98 |
99 | For the sake of brevity, the `api_key` parameter will be omitted from the examples in this documentation. Remember to always include it in your actual queries.
100 |
101 | Note that the Open Hub API previously required the use of a version parameter `v`. This is no longer required, and will be ignored.
102 |
103 | ## XML Response Format
104 |
105 | A sample response to a project request might be:
106 |
107 | ```xml
108 |
109 |
110 | success
111 |
112 |
113 | 1
114 | Subversion
115 | 2006-10-10T15:51:31Z
116 | 2007-08-22T17:31:17Z
117 | Subversion has rapidly become the version control standard....
118 | http://subversion.tigris.org/
119 | http://subversion.tigris.org/project_packages.html
120 |
121 | 1096
122 | 51898
123 |
124 | 51898
125 | 1
126 | 2007-07-12T12:21:11Z
127 | 2007-07-12T12:18:54Z
128 | 2001-08-01T00:00:00Z
129 | 2007-07-01T00:00:00Z
130 | 55
131 | 319283
132 | 7
133 | C/C++
134 |
135 |
136 |
137 |
138 | ```
139 |
140 | All XML returned from the Open Hub API will be contained within a root element called ``, which will always contain a `` element.
141 |
142 | The `` element will contain either `success` or `failed`.
143 |
144 | When the `` value is `success`, the HTTP response code will be `200`, and the `` element contains the data you requested.
145 |
146 | If the `status` is `failed`, then the HTTP response code will be set appropriately (usually Bad Request or Not Found), and an `` element will be present containing human-readable help text. For example:
147 |
148 | ```xml
149 |
150 |
151 | failed
152 | A valid api_key is required to access this URL.
153 |
154 | ```
155 |
156 | Details about this project response can be found in the Open Hub API Reference [project page](reference/project.md).
157 |
158 | ## Collection Requests
159 |
160 | ### Collection Request Parameters
161 |
162 | + __query__ - Results will be filtered by the provided string. Only items that contain the query string in their names or descriptions will be returned. Filtering is case insenstive. Only alphanumeric characters are accepted. All non-alphanumeric characters will be replaced by spaces. Filtering is not available on all API methods, and the searched text depends on the type of object requested. Check the reference documentation for specifics.
163 | + __sort__ - Controls the sort order of the returned results. Typical supported values are name, created_at, and updated_at. The specific sort options available depend on the type of object requested, so check to the reference documentation for specifics. _API does not support reverse sorting_.
164 | + __page__ - In most cases, the Open Hub API returns at most 25 items per request. Pass this parameter to request subsequent items beyond the first page. This parameter is _one-based_, with a default value of 1. If you pass a value outside the range of available pages, you will receive the first page.
165 |
166 | For example, to get the second page of projects containing “java” or “Java” in their titles, descriptions, or tags, you would request:
167 |
168 | ```
169 | GET https://www.openhub.net/p.xml?query=java&page=2
170 | ```
171 |
172 | ### Collection Response XML Format
173 |
174 | Some results will contain a collection of values. When this happens, the `` element will contain some additional elements:
175 |
176 | + __items_returned__ - The number of items returned in this response.
177 | + __items_available__ - The total number of database items matching the query, including those already returned.
178 | + __first_item_position__ - The zero-based index of the first item returned
179 |
180 | For example, the response to `https://www.openhub.net/p.xml` might begin:
181 |
182 | ```xml
183 |
184 | success
185 | 25
186 | 7056
187 | 0
188 |
189 |
190 | 9
191 | Mozilla Firefox
192 | ....
193 | ```
194 |
195 | - - -
196 | Copyright 2025 Black Duck Software, Inc. Unless otherwise marked, this work is licensed under a [Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/).
197 |
--------------------------------------------------------------------------------
/email_lookup.md:
--------------------------------------------------------------------------------
1 | ## Lookup By Email
2 |
3 | The Open Hub API allows you to retrieve an [Account](reference/account.md) using the MD5 hash of the account’s email address.
4 |
5 | You can pass the MD5 hash of an email address in any URL that normally expects an Account ID.
6 |
7 | This is useful if you know someone’s email address, but do not know the Open Hub account ID. This might be the case if you are hosting a web site with registered users who have supplied their email addresses. With the Open Hub API, you can easily find Open Hub statistics about your registered users.
8 |
9 | For example, here’s how to find the account data for `info@openhub.net`:
10 | + Generate the MD5 hash for `info@openhub.net`. From a irb shell you can do this simply:
11 | ```shell
12 | require 'digest'
13 | Digest::MD5.hexdigest('info@openhub.net').to_s
14 | f1c4c8746d8e42872f6db32977ad5d61
15 | ```
16 |
17 | + Pass this hash in place of the account ID in the normal http request:
18 | ```shell
19 | $ curl https://www.openhub.net/accounts/f1c4c8746d8e42872f6db32977ad5d61.xml?api_key=
20 | ```
21 |
22 | Open Hub does not publish email addresses. You must already know the email address of the account you are looking for. Because the search is done using the MD5 hash of the email address, the email address comparison is case sensitive and must match exactly.
23 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/bin/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackducksoftware/ohloh_api/c369980fca22b7724371c95e2837f830ad51983e/examples/ApiExample.cpp/bin/.gitkeep
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/build/vs2005/OhlohApiExample.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 9.00
3 | # Visual Studio 2005
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenHubApiExample", "OpenHubApiExample.vcproj", "{EA66C001-B006-4DBA-9542-A5E887BA420C}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | debug|Win32 = debug|Win32
9 | release|Win32 = release|Win32
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {EA66C001-B006-4DBA-9542-A5E887BA420C}.debug|Win32.ActiveCfg = debug|Win32
13 | {EA66C001-B006-4DBA-9542-A5E887BA420C}.debug|Win32.Build.0 = debug|Win32
14 | {EA66C001-B006-4DBA-9542-A5E887BA420C}.release|Win32.ActiveCfg = release|Win32
15 | {EA66C001-B006-4DBA-9542-A5E887BA420C}.release|Win32.Build.0 = release|Win32
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/build/vs2005/OhlohApiExample.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
26 |
29 |
32 |
35 |
38 |
41 |
57 |
60 |
63 |
66 |
79 |
82 |
88 |
91 |
94 |
97 |
100 |
103 |
106 |
107 |
115 |
118 |
121 |
124 |
127 |
130 |
139 |
142 |
145 |
148 |
157 |
160 |
163 |
166 |
169 |
172 |
175 |
178 |
181 |
182 |
183 |
184 |
185 |
186 |
191 |
194 |
195 |
198 |
199 |
202 |
203 |
206 |
207 |
210 |
211 |
214 |
215 |
218 |
219 |
222 |
223 |
224 |
229 |
232 |
233 |
236 |
237 |
240 |
241 |
244 |
245 |
248 |
249 |
252 |
253 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/compile.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # The MIT License (MIT)
3 | #
4 | # Copyright (c) 2013 Lars Wesselius
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 |
24 | cd src/
25 | make
26 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/include/HTTPDownload.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2013 Lars Wesselius
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 | */
24 |
25 | #ifndef __HTTPDOWNLOAD_H__
26 | #define __HTTPDOWNLOAD_H__
27 |
28 | #include "TCPSocket.h"
29 |
30 | #include
31 | #include
32 |
33 | class HTTPDownload
34 | {
35 | public:
36 | HTTPDownload(void) { }
37 | virtual ~HTTPDownload(void) { }
38 |
39 | bool start(const std::string &url);
40 | void stop(void);
41 |
42 | protected:
43 | bool _parseHeader(const std::string &header);
44 | bool _download(const std::string &url);
45 |
46 | TCPSocket *mSocket;
47 | std::ofstream mFile;
48 | };
49 |
50 | #endif
51 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/include/TCPSocket.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2013 Lars Wesselius
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 | */
24 |
25 | #ifndef __TCP_SOCKET_H__
26 | #define __TCP_SOCKET_H__
27 |
28 |
29 | #include
30 |
31 | class TCPSocket
32 | {
33 | public:
34 | TCPSocket(void);
35 | ~TCPSocket(void);
36 |
37 | void connect(const std::string &server, const int &port);
38 | void disconnect(void);
39 | bool connected(void) { return mSocket; }
40 |
41 | void send(const std::string &msg);
42 | int recieve(std::string &ret);
43 | bool eof(void) { return mEOF; }
44 |
45 | protected:
46 | int mSocket;
47 | bool mEOF;
48 | };
49 |
50 | #endif
51 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/include/main.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2013 Lars Wesselius
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 | */
24 |
25 | #ifndef __MAIN_H__
26 | #define __MAIN_H__
27 |
28 | #if defined( __WIN32__ ) || defined( _WIN32 )
29 | # define OS_WINDOWS
30 | # include
31 | #else
32 | # define OS_LINUX
33 | # include
34 | # include
35 | # include
36 | # include
37 | # include
38 | # include
39 | # include
40 | # include
41 | # include
42 | #endif
43 |
44 | #include
45 | #include
46 |
47 |
48 | std::pair parseCommandLine(int argc, const char * argv[]);
49 | void parseAndShowResult();
50 |
51 | #endif
52 |
53 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/include/md5.h:
--------------------------------------------------------------------------------
1 | // MD5.CC - source code for the C++/object oriented translation and
2 | // modification of MD5.
3 |
4 | // Translation and modification (c) 1995 by Mordechai T. Abzug
5 |
6 | // This translation/ modification is provided "as is," without express or
7 | // implied warranty of any kind.
8 |
9 | // The translator/ modifier does not claim (1) that MD5 will do what you think
10 | // it does; (2) that this translation/ modification is accurate; or (3) that
11 | // this software is "merchantible." (Language for this disclaimer partially
12 | // copied from the disclaimer below).
13 |
14 | /* based on:
15 |
16 | MD5.H - header file for MD5C.C
17 | MDDRIVER.C - test driver for MD2, MD4 and MD5
18 |
19 | Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
20 | rights reserved.
21 |
22 | License to copy and use this software is granted provided that it
23 | is identified as the "RSA Data Security, Inc. MD5 Message-Digest
24 | Algorithm" in all material mentioning or referencing this software
25 | or this function.
26 |
27 | License is also granted to make and use derivative works provided
28 | that such works are identified as "derived from the RSA Data
29 | Security, Inc. MD5 Message-Digest Algorithm" in all material
30 | mentioning or referencing the derived work.
31 |
32 | RSA Data Security, Inc. makes no representations concerning either
33 | the merchantability of this software or the suitability of this
34 | software for any particular purpose. It is provided "as is"
35 | without express or implied warranty of any kind.
36 |
37 | These notices must be retained in any copies of any part of this
38 | documentation and/or software.
39 |
40 | */
41 |
42 | #include
43 | #include
44 | #include
45 |
46 | using namespace std;
47 |
48 | class MD5 {
49 |
50 | public:
51 | // methods for controlled operation:
52 | MD5 (); // simple initializer
53 | void update (unsigned char *input, unsigned int input_length);
54 | void update (istream& stream);
55 | void update (ifstream& stream);
56 | void finalize ();
57 |
58 | // constructors for special circumstances. All these constructors finalize
59 | // the MD5 context.
60 | MD5 (unsigned char *string); // digest string, finalize
61 | MD5 (istream& stream); // digest stream, finalize
62 | MD5 (ifstream& stream); // digest stream, close, finalize
63 |
64 | // methods to acquire finalized result
65 | unsigned char *raw_digest (); // digest as a 16-byte binary array
66 | char * hex_digest (); // digest as a 33-byte ascii-hex string
67 | friend ostream& operator<< (ostream&, MD5 context);
68 |
69 |
70 |
71 | private:
72 |
73 | // first, some types:
74 | typedef unsigned int uint4; // assumes integer is 4 words long
75 | typedef unsigned short int uint2; // assumes short integer is 2 words long
76 | typedef unsigned char uint1; // assumes char is 1 word long
77 |
78 | // next, the private data:
79 | uint4 state[4];
80 | uint4 count[2]; // number of *bits*, mod 2^64
81 | uint1 buffer[64]; // input buffer
82 | uint1 digest[16];
83 | uint1 finalized;
84 |
85 | // last, the private methods, mostly static:
86 | void init (); // called by all constructors
87 | void transform (uint1 *buffer); // does the real update work. Note
88 | // that length is implied to be 64.
89 |
90 | static void encode (uint1 *dest, uint4 *src, uint4 length);
91 | static void decode (uint4 *dest, uint1 *src, uint4 length);
92 | static void memcpy (uint1 *dest, uint1 *src, uint4 length);
93 | static void memset (uint1 *start, uint1 val, uint4 length);
94 |
95 | static inline uint4 rotate_left (uint4 x, uint4 n);
96 | static inline uint4 F (uint4 x, uint4 y, uint4 z);
97 | static inline uint4 G (uint4 x, uint4 y, uint4 z);
98 | static inline uint4 H (uint4 x, uint4 y, uint4 z);
99 | static inline uint4 I (uint4 x, uint4 y, uint4 z);
100 | static inline void FF (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
101 | uint4 s, uint4 ac);
102 | static inline void GG (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
103 | uint4 s, uint4 ac);
104 | static inline void HH (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
105 | uint4 s, uint4 ac);
106 | static inline void II (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
107 | uint4 s, uint4 ac);
108 |
109 | };
110 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/include/tinystr.h:
--------------------------------------------------------------------------------
1 | /*
2 | www.sourceforge.net/projects/tinyxml
3 | Original file by Yves Berquin.
4 |
5 | This software is provided 'as-is', without any express or implied
6 | warranty. In no event will the authors be held liable for any
7 | damages arising from the use of this software.
8 |
9 | Permission is granted to anyone to use this software for any
10 | purpose, including commercial applications, and to alter it and
11 | redistribute it freely, subject to the following restrictions:
12 |
13 | 1. The origin of this software must not be misrepresented; you must
14 | not claim that you wrote the original software. If you use this
15 | software in a product, an acknowledgment in the product documentation
16 | would be appreciated but is not required.
17 |
18 | 2. Altered source versions must be plainly marked as such, and
19 | must not be misrepresented as being the original software.
20 |
21 | 3. This notice may not be removed or altered from any source
22 | distribution.
23 | */
24 |
25 | /*
26 | * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
27 | *
28 | * - completely rewritten. compact, clean, and fast implementation.
29 | * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
30 | * - fixed reserve() to work as per specification.
31 | * - fixed buggy compares operator==(), operator<(), and operator>()
32 | * - fixed operator+=() to take a const ref argument, following spec.
33 | * - added "copy" constructor with length, and most compare operators.
34 | * - added swap(), clear(), size(), capacity(), operator+().
35 | */
36 |
37 | #ifndef TIXML_USE_STL
38 |
39 | #ifndef TIXML_STRING_INCLUDED
40 | #define TIXML_STRING_INCLUDED
41 |
42 | #include
43 | #include
44 |
45 | /* The support for explicit isn't that universal, and it isn't really
46 | required - it is used to check that the TiXmlString class isn't incorrectly
47 | used. Be nice to old compilers and macro it here:
48 | */
49 | #if defined(_MSC_VER) && (_MSC_VER >= 1200 )
50 | // Microsoft visual studio, version 6 and higher.
51 | #define TIXML_EXPLICIT explicit
52 | #elif defined(__GNUC__) && (__GNUC__ >= 3 )
53 | // GCC version 3 and higher.s
54 | #define TIXML_EXPLICIT explicit
55 | #else
56 | #define TIXML_EXPLICIT
57 | #endif
58 |
59 |
60 | /*
61 | TiXmlString is an emulation of a subset of the std::string template.
62 | Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
63 | Only the member functions relevant to the TinyXML project have been implemented.
64 | The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
65 | a string and there's no more room, we allocate a buffer twice as big as we need.
66 | */
67 | class TiXmlString
68 | {
69 | public :
70 | // The size type used
71 | typedef size_t size_type;
72 |
73 | // Error value for find primitive
74 | static const size_type npos; // = -1;
75 |
76 |
77 | // TiXmlString empty constructor
78 | TiXmlString () : rep_(&nullrep_)
79 | {
80 | }
81 |
82 | // TiXmlString copy constructor
83 | TiXmlString ( const TiXmlString & copy) : rep_(0)
84 | {
85 | init(copy.length());
86 | memcpy(start(), copy.data(), length());
87 | }
88 |
89 | // TiXmlString constructor, based on a string
90 | TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
91 | {
92 | init( static_cast( strlen(copy) ));
93 | memcpy(start(), copy, length());
94 | }
95 |
96 | // TiXmlString constructor, based on a string
97 | TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
98 | {
99 | init(len);
100 | memcpy(start(), str, len);
101 | }
102 |
103 | // TiXmlString destructor
104 | ~TiXmlString ()
105 | {
106 | quit();
107 | }
108 |
109 | // = operator
110 | TiXmlString& operator = (const char * copy)
111 | {
112 | return assign( copy, (size_type)strlen(copy));
113 | }
114 |
115 | // = operator
116 | TiXmlString& operator = (const TiXmlString & copy)
117 | {
118 | return assign(copy.start(), copy.length());
119 | }
120 |
121 |
122 | // += operator. Maps to append
123 | TiXmlString& operator += (const char * suffix)
124 | {
125 | return append(suffix, static_cast( strlen(suffix) ));
126 | }
127 |
128 | // += operator. Maps to append
129 | TiXmlString& operator += (char single)
130 | {
131 | return append(&single, 1);
132 | }
133 |
134 | // += operator. Maps to append
135 | TiXmlString& operator += (const TiXmlString & suffix)
136 | {
137 | return append(suffix.data(), suffix.length());
138 | }
139 |
140 |
141 | // Convert a TiXmlString into a null-terminated char *
142 | const char * c_str () const { return rep_->str; }
143 |
144 | // Convert a TiXmlString into a char * (need not be null terminated).
145 | const char * data () const { return rep_->str; }
146 |
147 | // Return the length of a TiXmlString
148 | size_type length () const { return rep_->size; }
149 |
150 | // Alias for length()
151 | size_type size () const { return rep_->size; }
152 |
153 | // Checks if a TiXmlString is empty
154 | bool empty () const { return rep_->size == 0; }
155 |
156 | // Return capacity of string
157 | size_type capacity () const { return rep_->capacity; }
158 |
159 |
160 | // single char extraction
161 | const char& at (size_type index) const
162 | {
163 | assert( index < length() );
164 | return rep_->str[ index ];
165 | }
166 |
167 | // [] operator
168 | char& operator [] (size_type index) const
169 | {
170 | assert( index < length() );
171 | return rep_->str[ index ];
172 | }
173 |
174 | // find a char in a string. Return TiXmlString::npos if not found
175 | size_type find (char lookup) const
176 | {
177 | return find(lookup, 0);
178 | }
179 |
180 | // find a char in a string from an offset. Return TiXmlString::npos if not found
181 | size_type find (char tofind, size_type offset) const
182 | {
183 | if (offset >= length()) return npos;
184 |
185 | for (const char* p = c_str() + offset; *p != '\0'; ++p)
186 | {
187 | if (*p == tofind) return static_cast< size_type >( p - c_str() );
188 | }
189 | return npos;
190 | }
191 |
192 | void clear ()
193 | {
194 | //Lee:
195 | //The original was just too strange, though correct:
196 | // TiXmlString().swap(*this);
197 | //Instead use the quit & re-init:
198 | quit();
199 | init(0,0);
200 | }
201 |
202 | /* Function to reserve a big amount of data when we know we'll need it. Be aware that this
203 | function DOES NOT clear the content of the TiXmlString if any exists.
204 | */
205 | void reserve (size_type cap);
206 |
207 | TiXmlString& assign (const char* str, size_type len);
208 |
209 | TiXmlString& append (const char* str, size_type len);
210 |
211 | void swap (TiXmlString& other)
212 | {
213 | Rep* r = rep_;
214 | rep_ = other.rep_;
215 | other.rep_ = r;
216 | }
217 |
218 | private:
219 |
220 | void init(size_type sz) { init(sz, sz); }
221 | void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
222 | char* start() const { return rep_->str; }
223 | char* finish() const { return rep_->str + rep_->size; }
224 |
225 | struct Rep
226 | {
227 | size_type size, capacity;
228 | char str[1];
229 | };
230 |
231 | void init(size_type sz, size_type cap)
232 | {
233 | if (cap)
234 | {
235 | // Lee: the original form:
236 | // rep_ = static_cast(operator new(sizeof(Rep) + cap));
237 | // doesn't work in some cases of new being overloaded. Switching
238 | // to the normal allocation, although use an 'int' for systems
239 | // that are overly picky about structure alignment.
240 | const size_type bytesNeeded = sizeof(Rep) + cap;
241 | const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int );
242 | rep_ = reinterpret_cast( new int[ intsNeeded ] );
243 |
244 | rep_->str[ rep_->size = sz ] = '\0';
245 | rep_->capacity = cap;
246 | }
247 | else
248 | {
249 | rep_ = &nullrep_;
250 | }
251 | }
252 |
253 | void quit()
254 | {
255 | if (rep_ != &nullrep_)
256 | {
257 | // The rep_ is really an array of ints. (see the allocator, above).
258 | // Cast it back before delete, so the compiler won't incorrectly call destructors.
259 | delete [] ( reinterpret_cast( rep_ ) );
260 | }
261 | }
262 |
263 | Rep * rep_;
264 | static Rep nullrep_;
265 |
266 | } ;
267 |
268 |
269 | inline bool operator == (const TiXmlString & a, const TiXmlString & b)
270 | {
271 | return ( a.length() == b.length() ) // optimization on some platforms
272 | && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare
273 | }
274 | inline bool operator < (const TiXmlString & a, const TiXmlString & b)
275 | {
276 | return strcmp(a.c_str(), b.c_str()) < 0;
277 | }
278 |
279 | inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
280 | inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; }
281 | inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
282 | inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
283 |
284 | inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
285 | inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
286 | inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
287 | inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
288 |
289 | TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
290 | TiXmlString operator + (const TiXmlString & a, const char* b);
291 | TiXmlString operator + (const char* a, const TiXmlString & b);
292 |
293 |
294 | /*
295 | TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
296 | Only the operators that we need for TinyXML have been developped.
297 | */
298 | class TiXmlOutStream : public TiXmlString
299 | {
300 | public :
301 |
302 | // TiXmlOutStream << operator.
303 | TiXmlOutStream & operator << (const TiXmlString & in)
304 | {
305 | *this += in;
306 | return *this;
307 | }
308 |
309 | // TiXmlOutStream << operator.
310 | TiXmlOutStream & operator << (const char * in)
311 | {
312 | *this += in;
313 | return *this;
314 | }
315 |
316 | } ;
317 |
318 | #endif // TIXML_STRING_INCLUDED
319 | #endif // TIXML_USE_STL
320 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/src/ApiExample:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackducksoftware/ohloh_api/c369980fca22b7724371c95e2837f830ad51983e/examples/ApiExample.cpp/src/ApiExample
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/src/HTTPDownload.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2013 Lars Wesselius
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 | */
24 |
25 | #include "HTTPDownload.h"
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | #define HTTP_RESPONSE_MAX_SIZE 65536
33 |
34 | /* HTTP/1.0 status codes from RFC1945, provided for reference. */
35 | /* Successful 2xx. */
36 | #define HTTP_STATUS_OK 200
37 | #define HTTP_STATUS_CREATED 201
38 | #define HTTP_STATUS_ACCEPTED 202
39 | #define HTTP_STATUS_NO_CONTENT 204
40 | #define HTTP_STATUS_PARTIAL_CONTENTS 206
41 |
42 | /* Redirection 3xx. */
43 | #define HTTP_STATUS_MULTIPLE_CHOICES 300
44 | #define HTTP_STATUS_MOVED_PERMANENTLY 301
45 | #define HTTP_STATUS_MOVED_TEMPORARILY 302
46 | #define HTTP_STATUS_SEE_OTHER 303 /* from HTTP/1.1 */
47 | #define HTTP_STATUS_NOT_MODIFIED 304
48 | #define HTTP_STATUS_TEMPORARY_REDIRECT 307 /* from HTTP/1.1 */
49 |
50 | /* Client error 4xx. */
51 | #define HTTP_STATUS_BAD_REQUEST 400
52 | #define HTTP_STATUS_UNAUTHORIZED 401
53 | #define HTTP_STATUS_FORBIDDEN 403
54 | #define HTTP_STATUS_NOT_FOUND 404
55 | #define HTTP_STATUS_RANGE_NOT_SATISFIABLE 416
56 |
57 | /* Server errors 5xx. */
58 | #define HTTP_STATUS_INTERNAL 500
59 | #define HTTP_STATUS_NOT_IMPLEMENTED 501
60 | #define HTTP_STATUS_BAD_GATEWAY 502
61 | #define HTTP_STATUS_UNAVAILABLE 503
62 |
63 | bool HTTPDownload::start(const std::string &url)
64 | {
65 | mSocket = new TCPSocket();
66 | return _download(url);
67 | }
68 |
69 | void HTTPDownload::stop()
70 | {
71 | delete mSocket;
72 | mSocket = 0;
73 | }
74 |
75 | bool HTTPDownload::_parseHeader(const std::string &header)
76 | {
77 | std::string line = header.substr(0, header.find_first_of('\n'));
78 | size_t index = 0, size = line.size();
79 |
80 | /* Check the HTTP of the header */
81 | if (line.compare(0,4, "HTTP") != 0)
82 | return false;
83 | index = 4;
84 |
85 | /* Check for the HTTP version of the header (it may not exist so skip it if its not there)*/
86 | if (index < size && line[index] == '/')
87 | {
88 | ++index;
89 | while (index < size && isdigit(line[index]))
90 | index++;
91 | if (index < size && line[index] == '.')
92 | index++;
93 | while (index < size && isdigit(line[index]))
94 | index++;
95 | }
96 | if (index < size && line[index] != ' ')
97 | return false;
98 | ++index;
99 |
100 | /* Get the status code */
101 | if (size - index < 3)
102 | return false;
103 | int status = atoi(line.substr(index, 3).c_str());
104 | index += 3;
105 | while (index < size && line[index] == ' ')
106 | ++index;
107 | std::string message = line.substr(index);
108 |
109 | /* Parse the status code */
110 | switch (status)
111 | {
112 | case HTTP_STATUS_BAD_REQUEST:
113 | case HTTP_STATUS_UNAUTHORIZED:
114 | case HTTP_STATUS_FORBIDDEN:
115 | case HTTP_STATUS_NOT_FOUND:
116 | case HTTP_STATUS_INTERNAL:
117 | case HTTP_STATUS_NOT_IMPLEMENTED:
118 | case HTTP_STATUS_BAD_GATEWAY:
119 | case HTTP_STATUS_UNAVAILABLE:
120 | return false;
121 | }
122 |
123 | std::string rest = header;
124 | index = rest.find_first_of('\r');
125 | std::map settings;
126 | while (index != std::string::npos)
127 | {
128 | rest = rest.substr(index);
129 | if (rest[0] == '\n' && rest[1] == '\r' && rest[2] == '\n')
130 | break;
131 |
132 | std::string line = rest.substr(0,rest.find('\r',1));
133 | while (line[0] == '\n' || line[0] == '\r' || line[0] == ' ' || line[0] == '\t')
134 | line = line.substr(1);
135 | size_t sep = line.find_first_of(':');
136 | if (sep != std::string::npos)
137 | {
138 | std::string value = line.substr(sep+1);
139 | while (value[0] == ' ')
140 | value = value.substr(1);
141 | settings.insert(std::make_pair(line.substr(0,sep), value));
142 | }
143 | index = rest.find('\r', 1);
144 | }
145 | if (((status > 299 && status < 308) && settings.find("Location") != settings.end()) || settings.find("Location") != settings.end())
146 | {
147 | std::cerr << "[Downloader] Download location has changed to " << settings["Location"] << "\n";
148 | mFile.close();
149 | _download(settings["Location"]);
150 | return false;
151 | }
152 |
153 | return true;
154 | }
155 |
156 | bool HTTPDownload::_download(const std::string &url)
157 | {
158 | std::string location;
159 | std::cout << url << std::endl;
160 |
161 | /* Check for correct url type and strip it */
162 | if (url.compare(0,7,"http://") != 0)
163 | {
164 | if (url.find("://") != std::string::npos)
165 | return false;
166 | location = url;
167 | }
168 | else
169 | {
170 | location = url.substr(7);
171 | }
172 |
173 | /* Get the server and the location of the file */
174 | std::string::size_type index = location.find_first_of('/');
175 | std::string::size_type dp = location.find_first_of(':');
176 |
177 | int port = 80;
178 | if (dp != std::string::npos && dp < index)
179 | {
180 | port = atoi(location.substr(dp+1, index).c_str());
181 | location = location.erase(dp, index-dp);
182 | index = dp;
183 | }
184 |
185 | std::string server = "";
186 | std::string fileLocation = "";
187 | std::string name = "";
188 | if (index == std::string::npos)
189 | {
190 | server = location;
191 | fileLocation = "";
192 | }
193 | else
194 | {
195 | server = location.substr(0,index);
196 | name = location.substr(location.find_last_of('/')+1);
197 | fileLocation = location.substr(index+1);
198 | }
199 |
200 | /* Do some error checking and force std names/locations */
201 | if (server.empty())
202 | {
203 | server = fileLocation;
204 | fileLocation = "";
205 | }
206 | if (name.empty())
207 | name = "index.html";
208 |
209 | mSocket->connect(server, port);
210 |
211 | if (mSocket->connected())
212 | {
213 | std::cout << "Connected." << std::endl;
214 | }
215 | else
216 | {
217 | std::cout << "Not connected." << std::endl;
218 | }
219 |
220 | std::cout << "Requesting file.." << std::endl;
221 | /* Send header .. */
222 | std::stringstream header;
223 | header << "GET /" << fileLocation << " HTTP/1.1\r\n";
224 | header << "Host: " << server << "\r\n";
225 | header << "Connection: Close\r\n";
226 | header << "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
227 | header << "User-Agent: Downloader 0.1 (i686; X11; Linux)\r\n\r\n";
228 |
229 | mSocket->send(header.str());
230 |
231 |
232 | std::string buf, httpheader;
233 | /* Recieve the first packet with the http header */
234 | mSocket->recieve(buf);
235 |
236 |
237 | /* Extract the REAL http header out of all the data */
238 | short i = 0;
239 | while (!(buf[i] == '\r' && buf[i+1] == '\n' && buf[i+2] == '\r' && buf[i+3] == '\n'))
240 | ++i;
241 |
242 | /* Parse the http header */
243 | if (!_parseHeader(buf.substr(0,i)))
244 | {
245 | std::cout << buf.substr(0, i) << std::endl;
246 | std::cout << "Request failed. Invalid api key?" << std::endl;
247 | return false;
248 | }
249 |
250 |
251 | /* Open the file which we're going to download */
252 | mFile.open("temp.xml", std::ios::trunc);
253 | mFile << buf.substr(i+4);
254 |
255 | short ret;
256 |
257 | /* Get the rest of the data */
258 | while (!mSocket->eof())
259 | {
260 | //std::cerr << buf;
261 | ret = mSocket->recieve(buf);
262 | mFile << buf;
263 | mFile.flush();
264 | }
265 | mFile.close();
266 |
267 | std::cout << "Request completed." << std::endl;
268 | mSocket->disconnect();
269 | return true;
270 | }
271 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/src/TCPSocket.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2013 Lars Wesselius
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 | */
24 |
25 | #include "TCPSocket.h"
26 | #include "main.h"
27 | #include
28 |
29 |
30 | #define RESPONSE_MAX_SIZE 65536
31 |
32 | TCPSocket::TCPSocket()
33 | {
34 | mSocket = 0;
35 | mEOF = false;
36 | }
37 |
38 | TCPSocket::~TCPSocket()
39 | {
40 |
41 | }
42 |
43 | void TCPSocket::connect(const std::string &server, const int &port)
44 | {
45 | struct hostent *he; // Host to connect to
46 | struct sockaddr_in server_addr; // Address of the server
47 |
48 | if ((he = gethostbyname(server.c_str())) == NULL)
49 | return;
50 |
51 | if ((mSocket = socket(PF_INET, SOCK_STREAM, 0)) == -1)
52 | return;
53 |
54 | server_addr.sin_family = AF_INET;
55 | server_addr.sin_port = htons(port);
56 | server_addr.sin_addr = *((struct in_addr *)he->h_addr);
57 | memset(server_addr.sin_zero, '\0', sizeof server_addr.sin_zero);
58 |
59 | if (::connect(mSocket,(struct sockaddr *)&server_addr, sizeof server_addr) == -1)
60 | return;
61 | }
62 |
63 | void TCPSocket::disconnect()
64 | {
65 | #ifdef OS_WINDOWS
66 | closesocket(mSocket);
67 | #else
68 | close(mSocket);
69 | #endif
70 | mSocket = 0;
71 | mEOF = false;
72 | }
73 |
74 | void TCPSocket::send(const std::string &msg)
75 | {
76 | int sended = 0;
77 | size_t tosend = msg.size();
78 | while (sended < tosend)
79 | {
80 | int n;
81 | if ((n = ::send(mSocket, msg.substr(sended).c_str(), tosend-sended, 0)) == -1)
82 | {
83 | mEOF = true;
84 | return;
85 | }
86 | sended += n;
87 | }
88 | }
89 |
90 | int TCPSocket::recieve(std::string &ret)
91 | {
92 | char buffer[RESPONSE_MAX_SIZE];
93 | int retv;
94 | if ((retv = recv(mSocket, buffer, RESPONSE_MAX_SIZE, 0)) == -1)
95 | {
96 | mEOF = true;
97 | return 0;
98 | }
99 | if (retv == 0)
100 | mEOF = true;
101 | ret = std::string(buffer, retv);
102 | return retv;
103 | }
104 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/src/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 |
4 |
5 | */
6 |
7 | /*
8 | MD5 algorithm implementation
9 | RSA Data Security, Inc. MD5 Message-Digest
10 | Algorithm
11 |
12 | For more details please consult md5.c
13 | */
14 | #include "main.h"
15 | #include "HTTPDownload.h"
16 | #include "md5.h"
17 | #include "tinyxml.h"
18 | #include
19 | #include
20 | #include
21 |
22 | int main(int argc, const char * argv[])
23 | {
24 | std::cout << std::endl << "Initializing.." << std::endl;
25 | #ifdef OS_WINDOWS
26 | WSADATA data;
27 | WSAStartup(MAKEWORD(1, 1), &data);
28 | #endif
29 | HTTPDownload * download = new HTTPDownload();
30 |
31 | std::pair infoPair = parseCommandLine(argc, argv);
32 |
33 | if (infoPair.first.empty() || infoPair.second.empty())
34 | {
35 | return 1;
36 | }
37 |
38 | std::cout << "Forming request.." << std::endl;
39 |
40 |
41 | std::istringstream str(infoPair.second);
42 | MD5 md5(str);
43 |
44 | std::string urlString = "https://www.openhub.net/accounts/";
45 | urlString += md5.hex_digest();
46 | urlString += ".xml?api_key=" + infoPair.first + "&v=1";
47 |
48 | if (download->start(urlString))
49 | {
50 | parseAndShowResult();
51 | }
52 |
53 | std::cout << std::endl << "Press the return key to exit." << std::endl;
54 | std::cin.get();
55 | return 1;
56 | }
57 |
58 | std::pair parseCommandLine(int argc, const char * argv[])
59 | {
60 | if (argc == 3)
61 | {
62 | return std::pair(argv[1], argv[2]);
63 | }
64 | else
65 | {
66 | std::cout << "Usage:" << std::endl;
67 | #ifdef OS_WINDOWS
68 | std::cout << "ApiExample.exe [api_key] [user_email]" << std::endl;
69 | #else
70 | std::cout << "./ApiExample [api_key] [user_email]" << std::endl;
71 | #endif
72 | }
73 |
74 | return std::pair("", "");
75 | }
76 |
77 | void parseAndShowResult()
78 | {
79 | std::cout << "Parsing file." << std::endl;
80 | TiXmlDocument doc("temp.xml");
81 | doc.LoadFile();
82 | TiXmlHandle docHandle(&doc);
83 |
84 | TiXmlElement * firstElements = docHandle.FirstChild("response").ToElement();
85 |
86 |
87 |
88 | TiXmlElement * statusElem = 0;
89 | statusElem = firstElements->FirstChildElement();
90 |
91 | if (!statusElem)
92 | {
93 | std::cout << "Corrupt file, wrong request made?" << std::endl;
94 | return;
95 | }
96 |
97 | if (std::string(statusElem->GetText()).compare("success") != 0)
98 | {
99 | TiXmlElement * errorElem = firstElements->FirstChildElement("error");
100 |
101 | std::cout << "Parsing failed with message: " << errorElem->GetText() << std::endl;
102 | return;
103 | }
104 |
105 | TiXmlElement * accountElement = firstElements->FirstChild("result")->FirstChild("account")->ToElement();
106 |
107 | TiXmlElement * nameElement = 0;
108 | nameElement = accountElement->FirstChildElement("name");
109 |
110 | if (nameElement == 0)
111 | {
112 | std::cout << "Parsing failed, could not find 'name' element." << std::endl;
113 | return;
114 | }
115 |
116 | std::cout << "Located name: " << nameElement->GetText() << std::endl;;
117 | }
118 |
119 |
120 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/src/makefile:
--------------------------------------------------------------------------------
1 | COMPILER = g++
2 | GCFLAGS = -I ../include/
3 |
4 | all:
5 | ${COMPILER} ${GCFLAGS} -o ../bin/ApiExample main.cpp HTTPDownload.cpp TCPSocket.cpp md5.cpp tinyxml.cpp tinystr.cpp tinyxmlerror.cpp tinyxmlparser.cpp
6 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/src/md5.cpp:
--------------------------------------------------------------------------------
1 | // MD5.CC - source code for the C++/object oriented translation and
2 | // modification of MD5.
3 |
4 | // Translation and modification (c) 1995 by Mordechai T. Abzug
5 |
6 | // This translation/ modification is provided "as is," without express or
7 | // implied warranty of any kind.
8 |
9 | // The translator/ modifier does not claim (1) that MD5 will do what you think
10 | // it does; (2) that this translation/ modification is accurate; or (3) that
11 | // this software is "merchantible." (Language for this disclaimer partially
12 | // copied from the disclaimer below).
13 |
14 | /* based on:
15 |
16 | MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
17 | MDDRIVER.C - test driver for MD2, MD4 and MD5
18 |
19 |
20 | Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
21 | rights reserved.
22 |
23 | License to copy and use this software is granted provided that it
24 | is identified as the "RSA Data Security, Inc. MD5 Message-Digest
25 | Algorithm" in all material mentioning or referencing this software
26 | or this function.
27 |
28 | License is also granted to make and use derivative works provided
29 | that such works are identified as "derived from the RSA Data
30 | Security, Inc. MD5 Message-Digest Algorithm" in all material
31 | mentioning or referencing the derived work.
32 |
33 | RSA Data Security, Inc. makes no representations concerning either
34 | the merchantability of this software or the suitability of this
35 | software for any particular purpose. It is provided "as is"
36 | without express or implied warranty of any kind.
37 |
38 | These notices must be retained in any copies of any part of this
39 | documentation and/or software.
40 |
41 | */
42 |
43 |
44 |
45 |
46 |
47 |
48 | #include "md5.h"
49 |
50 | #include
51 | #include
52 | #include
53 |
54 |
55 |
56 |
57 | // MD5 simple initialization method
58 |
59 | MD5::MD5(){
60 |
61 | init();
62 |
63 | }
64 |
65 |
66 |
67 |
68 | // MD5 block update operation. Continues an MD5 message-digest
69 | // operation, processing another message block, and updating the
70 | // context.
71 |
72 | void MD5::update (uint1 *input, uint4 input_length) {
73 |
74 | uint4 input_index, buffer_index;
75 | uint4 buffer_space; // how much space is left in buffer
76 |
77 | if (finalized){ // so we can't update!
78 | cerr << "MD5::update: Can't update a finalized digest!" << endl;
79 | return;
80 | }
81 |
82 | // Compute number of bytes mod 64
83 | buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
84 |
85 | // Update number of bits
86 | if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
87 | count[1]++;
88 |
89 | count[1] += ((uint4)input_length >> 29);
90 |
91 |
92 | buffer_space = 64 - buffer_index; // how much space is left in buffer
93 |
94 | // Transform as many times as possible.
95 | if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
96 | // fill the rest of the buffer and transform
97 | memcpy (buffer + buffer_index, input, buffer_space);
98 | transform (buffer);
99 |
100 | // now, transform each 64-byte piece of the input, bypassing the buffer
101 | for (input_index = buffer_space; input_index + 63 < input_length;
102 | input_index += 64)
103 | transform (input+input_index);
104 |
105 | buffer_index = 0; // so we can buffer remaining
106 | }
107 | else
108 | input_index=0; // so we can buffer the whole input
109 |
110 |
111 | // and here we do the buffering:
112 | memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
113 | }
114 |
115 |
116 | // MD5 update for istreams.
117 | // Like update for files; see above.
118 |
119 | void MD5::update(istream& stream){
120 |
121 | unsigned char buffer[1024];
122 | int len;
123 |
124 | while (stream.good()){
125 | stream.read((char*)buffer, 1024); // note that return value of read is unusable.
126 | len=stream.gcount();
127 | update(buffer, len);
128 | }
129 |
130 | }
131 |
132 |
133 |
134 |
135 |
136 |
137 | // MD5 update for ifstreams.
138 | // Like update for files; see above.
139 |
140 | void MD5::update(ifstream& stream){
141 |
142 | unsigned char buffer[1024];
143 | int len;
144 |
145 | while (stream.good()){
146 | stream.read((char*)buffer, 1024); // note that return value of read is unusable.
147 | len=stream.gcount();
148 | update(buffer, len);
149 | }
150 |
151 | }
152 |
153 |
154 |
155 |
156 |
157 |
158 | // MD5 finalization. Ends an MD5 message-digest operation, writing the
159 | // the message digest and zeroizing the context.
160 |
161 |
162 | void MD5::finalize (){
163 |
164 | unsigned char bits[8];
165 | unsigned int index, padLen;
166 | static uint1 PADDING[64]={
167 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
168 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
169 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
170 | };
171 |
172 | if (finalized){
173 | cerr << "MD5::finalize: Already finalized this digest!" << endl;
174 | return;
175 | }
176 |
177 | // Save number of bits
178 | encode (bits, count, 8);
179 |
180 | // Pad out to 56 mod 64.
181 | index = (uint4) ((count[0] >> 3) & 0x3f);
182 | padLen = (index < 56) ? (56 - index) : (120 - index);
183 | update (PADDING, padLen);
184 |
185 | // Append length (before padding)
186 | update (bits, 8);
187 |
188 | // Store state in digest
189 | encode (digest, state, 16);
190 |
191 | // Zeroize sensitive information
192 | memset (buffer, 0, sizeof(*buffer));
193 |
194 | finalized=1;
195 |
196 | }
197 |
198 | MD5::MD5(istream& stream){
199 |
200 | init(); // must called by all constructors
201 | update (stream);
202 | finalize();
203 | }
204 |
205 |
206 |
207 | MD5::MD5(ifstream& stream){
208 |
209 | init(); // must called by all constructors
210 | update (stream);
211 | finalize();
212 | }
213 |
214 |
215 |
216 | unsigned char *MD5::raw_digest(){
217 |
218 | uint1 *s = new uint1[16];
219 |
220 | if (!finalized){
221 | cerr << "MD5::raw_digest: Can't get digest if you haven't "<<
222 | "finalized the digest!" <> 8) & 0xff);
410 | output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
411 | output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
412 | }
413 | }
414 |
415 |
416 |
417 |
418 | // Decodes input (unsigned char) into output (UINT4). Assumes len is
419 | // a multiple of 4.
420 | void MD5::decode (uint4 *output, uint1 *input, uint4 len){
421 |
422 | unsigned int i, j;
423 |
424 | for (i = 0, j = 0; j < len; i++, j += 4)
425 | output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
426 | (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
427 | }
428 |
429 |
430 |
431 |
432 |
433 | // Note: Replace "for loop" with standard memcpy if possible.
434 | void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
435 |
436 | unsigned int i;
437 |
438 | for (i = 0; i < len; i++)
439 | output[i] = input[i];
440 | }
441 |
442 |
443 |
444 | // Note: Replace "for loop" with standard memset if possible.
445 | void MD5::memset (uint1 *output, uint1 value, uint4 len){
446 |
447 | unsigned int i;
448 |
449 | for (i = 0; i < len; i++)
450 | output[i] = value;
451 | }
452 |
453 |
454 |
455 | // ROTATE_LEFT rotates x left n bits.
456 |
457 | inline unsigned int MD5::rotate_left (uint4 x, uint4 n){
458 | return (x << n) | (x >> (32-n)) ;
459 | }
460 |
461 |
462 |
463 |
464 | // F, G, H and I are basic MD5 functions.
465 |
466 | inline unsigned int MD5::F (uint4 x, uint4 y, uint4 z){
467 | return (x & y) | (~x & z);
468 | }
469 |
470 | inline unsigned int MD5::G (uint4 x, uint4 y, uint4 z){
471 | return (x & z) | (y & ~z);
472 | }
473 |
474 | inline unsigned int MD5::H (uint4 x, uint4 y, uint4 z){
475 | return x ^ y ^ z;
476 | }
477 |
478 | inline unsigned int MD5::I (uint4 x, uint4 y, uint4 z){
479 | return y ^ (x | ~z);
480 | }
481 |
482 |
483 |
484 | // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
485 | // Rotation is separate from addition to prevent recomputation.
486 |
487 |
488 | inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
489 | uint4 s, uint4 ac){
490 | a += F(b, c, d) + x + ac;
491 | a = rotate_left (a, s) +b;
492 | }
493 |
494 | inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
495 | uint4 s, uint4 ac){
496 | a += G(b, c, d) + x + ac;
497 | a = rotate_left (a, s) +b;
498 | }
499 |
500 | inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
501 | uint4 s, uint4 ac){
502 | a += H(b, c, d) + x + ac;
503 | a = rotate_left (a, s) +b;
504 | }
505 |
506 | inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
507 | uint4 s, uint4 ac){
508 | a += I(b, c, d) + x + ac;
509 | a = rotate_left (a, s) +b;
510 | }
511 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/src/tinystr.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackducksoftware/ohloh_api/c369980fca22b7724371c95e2837f830ad51983e/examples/ApiExample.cpp/src/tinystr.cpp
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/src/tinyxmlerror.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | www.sourceforge.net/projects/tinyxml
3 | Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
4 |
5 | This software is provided 'as-is', without any express or implied
6 | warranty. In no event will the authors be held liable for any
7 | damages arising from the use of this software.
8 |
9 | Permission is granted to anyone to use this software for any
10 | purpose, including commercial applications, and to alter it and
11 | redistribute it freely, subject to the following restrictions:
12 |
13 | 1. The origin of this software must not be misrepresented; you must
14 | not claim that you wrote the original software. If you use this
15 | software in a product, an acknowledgment in the product documentation
16 | would be appreciated but is not required.
17 |
18 | 2. Altered source versions must be plainly marked as such, and
19 | must not be misrepresented as being the original software.
20 |
21 | 3. This notice may not be removed or altered from any source
22 | distribution.
23 | */
24 |
25 |
26 | #include "tinyxml.h"
27 |
28 | // The goal of the seperate error file is to make the first
29 | // step towards localization. tinyxml (currently) only supports
30 | // english error messages, but the could now be translated.
31 | //
32 | // It also cleans up the code a bit.
33 | //
34 |
35 | const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
36 | {
37 | "No error",
38 | "Error",
39 | "Failed to open file",
40 | "Memory allocation failed.",
41 | "Error parsing Element.",
42 | "Failed to read Element name",
43 | "Error reading Element value.",
44 | "Error reading Attributes.",
45 | "Error: empty tag.",
46 | "Error reading end tag.",
47 | "Error parsing Unknown.",
48 | "Error parsing Comment.",
49 | "Error parsing Declaration.",
50 | "Error document empty.",
51 | "Error null (0) or unexpected EOF found in input stream.",
52 | "Error parsing CDATA.",
53 | "Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
54 | };
55 |
--------------------------------------------------------------------------------
/examples/ApiExample.cpp/src/tinyxmlparser.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | www.sourceforge.net/projects/tinyxml
3 | Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
4 |
5 | This software is provided 'as-is', without any express or implied
6 | warranty. In no event will the authors be held liable for any
7 | damages arising from the use of this software.
8 |
9 | Permission is granted to anyone to use this software for any
10 | purpose, including commercial applications, and to alter it and
11 | redistribute it freely, subject to the following restrictions:
12 |
13 | 1. The origin of this software must not be misrepresented; you must
14 | not claim that you wrote the original software. If you use this
15 | software in a product, an acknowledgment in the product documentation
16 | would be appreciated but is not required.
17 |
18 | 2. Altered source versions must be plainly marked as such, and
19 | must not be misrepresented as being the original software.
20 |
21 | 3. This notice may not be removed or altered from any source
22 | distribution.
23 | */
24 |
25 |
26 | #include
27 | #include
28 |
29 | #include "tinyxml.h"
30 |
31 | //#define DEBUG_PARSER
32 | #if defined( DEBUG_PARSER )
33 | # if defined( DEBUG ) && defined( _MSC_VER )
34 | # include
35 | # define TIXML_LOG OutputDebugString
36 | # else
37 | # define TIXML_LOG printf
38 | # endif
39 | #endif
40 |
41 | // Note tha "PutString" hardcodes the same list. This
42 | // is less flexible than it appears. Changing the entries
43 | // or order will break putstring.
44 | TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] =
45 | {
46 | { "&", 5, '&' },
47 | { "<", 4, '<' },
48 | { ">", 4, '>' },
49 | { """, 6, '\"' },
50 | { "'", 6, '\'' }
51 | };
52 |
53 | // Bunch of unicode info at:
54 | // http://www.unicode.org/faq/utf_bom.html
55 | // Including the basic of this table, which determines the #bytes in the
56 | // sequence from the lead byte. 1 placed for invalid sequences --
57 | // although the result will be junk, pass it through as much as possible.
58 | // Beware of the non-characters in UTF-8:
59 | // ef bb bf (Microsoft "lead bytes")
60 | // ef bf be
61 | // ef bf bf
62 |
63 | const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
64 | const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
65 | const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
66 |
67 | const int TiXmlBase::utf8ByteTable[256] =
68 | {
69 | // 0 1 2 3 4 5 6 7 8 9 a b c d e f
70 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
71 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
72 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20
73 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30
74 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40
75 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50
76 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60
77 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range
78 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid
79 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
80 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
81 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
82 | 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte
83 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0
84 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte
85 | 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
86 | };
87 |
88 |
89 | void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
90 | {
91 | const unsigned long BYTE_MASK = 0xBF;
92 | const unsigned long BYTE_MARK = 0x80;
93 | const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
94 |
95 | if (input < 0x80)
96 | *length = 1;
97 | else if ( input < 0x800 )
98 | *length = 2;
99 | else if ( input < 0x10000 )
100 | *length = 3;
101 | else if ( input < 0x200000 )
102 | *length = 4;
103 | else
104 | { *length = 0; return; } // This code won't covert this correctly anyway.
105 |
106 | output += *length;
107 |
108 | // Scary scary fall throughs.
109 | switch (*length)
110 | {
111 | case 4:
112 | --output;
113 | *output = (char)((input | BYTE_MARK) & BYTE_MASK);
114 | input >>= 6;
115 | case 3:
116 | --output;
117 | *output = (char)((input | BYTE_MARK) & BYTE_MASK);
118 | input >>= 6;
119 | case 2:
120 | --output;
121 | *output = (char)((input | BYTE_MARK) & BYTE_MASK);
122 | input >>= 6;
123 | case 1:
124 | --output;
125 | *output = (char)(input | FIRST_BYTE_MARK[*length]);
126 | }
127 | }
128 |
129 |
130 | /*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
131 | {
132 | // This will only work for low-ascii, everything else is assumed to be a valid
133 | // letter. I'm not sure this is the best approach, but it is quite tricky trying
134 | // to figure out alhabetical vs. not across encoding. So take a very
135 | // conservative approach.
136 |
137 | // if ( encoding == TIXML_ENCODING_UTF8 )
138 | // {
139 | if ( anyByte < 127 )
140 | return isalpha( anyByte );
141 | else
142 | return 1; // What else to do? The unicode set is huge...get the english ones right.
143 | // }
144 | // else
145 | // {
146 | // return isalpha( anyByte );
147 | // }
148 | }
149 |
150 |
151 | /*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
152 | {
153 | // This will only work for low-ascii, everything else is assumed to be a valid
154 | // letter. I'm not sure this is the best approach, but it is quite tricky trying
155 | // to figure out alhabetical vs. not across encoding. So take a very
156 | // conservative approach.
157 |
158 | // if ( encoding == TIXML_ENCODING_UTF8 )
159 | // {
160 | if ( anyByte < 127 )
161 | return isalnum( anyByte );
162 | else
163 | return 1; // What else to do? The unicode set is huge...get the english ones right.
164 | // }
165 | // else
166 | // {
167 | // return isalnum( anyByte );
168 | // }
169 | }
170 |
171 |
172 | class TiXmlParsingData
173 | {
174 | friend class TiXmlDocument;
175 | public:
176 | void Stamp( const char* now, TiXmlEncoding encoding );
177 |
178 | const TiXmlCursor& Cursor() { return cursor; }
179 |
180 | private:
181 | // Only used by the document!
182 | TiXmlParsingData( const char* start, int _tabsize, int row, int col )
183 | {
184 | assert( start );
185 | stamp = start;
186 | tabsize = _tabsize;
187 | cursor.row = row;
188 | cursor.col = col;
189 | }
190 |
191 | TiXmlCursor cursor;
192 | const char* stamp;
193 | int tabsize;
194 | };
195 |
196 |
197 | void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
198 | {
199 | assert( now );
200 |
201 | // Do nothing if the tabsize is 0.
202 | if ( tabsize < 1 )
203 | {
204 | return;
205 | }
206 |
207 | // Get the current row, column.
208 | int row = cursor.row;
209 | int col = cursor.col;
210 | const char* p = stamp;
211 | assert( p );
212 |
213 | while ( p < now )
214 | {
215 | // Treat p as unsigned, so we have a happy compiler.
216 | const unsigned char* pU = (const unsigned char*)p;
217 |
218 | // Code contributed by Fletcher Dunn: (modified by lee)
219 | switch (*pU) {
220 | case 0:
221 | // We *should* never get here, but in case we do, don't
222 | // advance past the terminating null character, ever
223 | return;
224 |
225 | case '\r':
226 | // bump down to the next line
227 | ++row;
228 | col = 0;
229 | // Eat the character
230 | ++p;
231 |
232 | // Check for \r\n sequence, and treat this as a single character
233 | if (*p == '\n') {
234 | ++p;
235 | }
236 | break;
237 |
238 | case '\n':
239 | // bump down to the next line
240 | ++row;
241 | col = 0;
242 |
243 | // Eat the character
244 | ++p;
245 |
246 | // Check for \n\r sequence, and treat this as a single
247 | // character. (Yes, this bizarre thing does occur still
248 | // on some arcane platforms...)
249 | if (*p == '\r') {
250 | ++p;
251 | }
252 | break;
253 |
254 | case '\t':
255 | // Eat the character
256 | ++p;
257 |
258 | // Skip to next tab stop
259 | col = (col / tabsize + 1) * tabsize;
260 | break;
261 |
262 | case TIXML_UTF_LEAD_0:
263 | if ( encoding == TIXML_ENCODING_UTF8 )
264 | {
265 | if ( *(p+1) && *(p+2) )
266 | {
267 | // In these cases, don't advance the column. These are
268 | // 0-width spaces.
269 | if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
270 | p += 3;
271 | else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
272 | p += 3;
273 | else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
274 | p += 3;
275 | else
276 | { p +=3; ++col; } // A normal character.
277 | }
278 | }
279 | else
280 | {
281 | ++p;
282 | ++col;
283 | }
284 | break;
285 |
286 | default:
287 | if ( encoding == TIXML_ENCODING_UTF8 )
288 | {
289 | // Eat the 1 to 4 byte utf8 character.
290 | int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
291 | if ( step == 0 )
292 | step = 1; // Error case from bad encoding, but handle gracefully.
293 | p += step;
294 |
295 | // Just advance one column, of course.
296 | ++col;
297 | }
298 | else
299 | {
300 | ++p;
301 | ++col;
302 | }
303 | break;
304 | }
305 | }
306 | cursor.row = row;
307 | cursor.col = col;
308 | assert( cursor.row >= -1 );
309 | assert( cursor.col >= -1 );
310 | stamp = p;
311 | assert( stamp );
312 | }
313 |
314 |
315 | const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
316 | {
317 | if ( !p || !*p )
318 | {
319 | return 0;
320 | }
321 | if ( encoding == TIXML_ENCODING_UTF8 )
322 | {
323 | while ( *p )
324 | {
325 | const unsigned char* pU = (const unsigned char*)p;
326 |
327 | // Skip the stupid Microsoft UTF-8 Byte order marks
328 | if ( *(pU+0)==TIXML_UTF_LEAD_0
329 | && *(pU+1)==TIXML_UTF_LEAD_1
330 | && *(pU+2)==TIXML_UTF_LEAD_2 )
331 | {
332 | p += 3;
333 | continue;
334 | }
335 | else if(*(pU+0)==TIXML_UTF_LEAD_0
336 | && *(pU+1)==0xbfU
337 | && *(pU+2)==0xbeU )
338 | {
339 | p += 3;
340 | continue;
341 | }
342 | else if(*(pU+0)==TIXML_UTF_LEAD_0
343 | && *(pU+1)==0xbfU
344 | && *(pU+2)==0xbfU )
345 | {
346 | p += 3;
347 | continue;
348 | }
349 |
350 | if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space.
351 | ++p;
352 | else
353 | break;
354 | }
355 | }
356 | else
357 | {
358 | while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' )
359 | ++p;
360 | }
361 |
362 | return p;
363 | }
364 |
365 | #ifdef TIXML_USE_STL
366 | /*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag )
367 | {
368 | for( ;; )
369 | {
370 | if ( !in->good() ) return false;
371 |
372 | int c = in->peek();
373 | // At this scope, we can't get to a document. So fail silently.
374 | if ( !IsWhiteSpace( c ) || c <= 0 )
375 | return true;
376 |
377 | *tag += (char) in->get();
378 | }
379 | }
380 |
381 | /*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag )
382 | {
383 | //assert( character > 0 && character < 128 ); // else it won't work in utf-8
384 | while ( in->good() )
385 | {
386 | int c = in->peek();
387 | if ( c == character )
388 | return true;
389 | if ( c <= 0 ) // Silent failure: can't get document at this scope
390 | return false;
391 |
392 | in->get();
393 | *tag += (char) c;
394 | }
395 | return false;
396 | }
397 | #endif
398 |
399 | // One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The
400 | // "assign" optimization removes over 10% of the execution time.
401 | //
402 | const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
403 | {
404 | // Oddly, not supported on some comilers,
405 | //name->clear();
406 | // So use this:
407 | *name = "";
408 | assert( p );
409 |
410 | // Names start with letters or underscores.
411 | // Of course, in unicode, tinyxml has no idea what a letter *is*. The
412 | // algorithm is generous.
413 | //
414 | // After that, they can be letters, underscores, numbers,
415 | // hyphens, or colons. (Colons are valid ony for namespaces,
416 | // but tinyxml can't tell namespaces from names.)
417 | if ( p && *p
418 | && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
419 | {
420 | const char* start = p;
421 | while( p && *p
422 | && ( IsAlphaNum( (unsigned char ) *p, encoding )
423 | || *p == '_'
424 | || *p == '-'
425 | || *p == '.'
426 | || *p == ':' ) )
427 | {
428 | //(*name) += *p; // expensive
429 | ++p;
430 | }
431 | if ( p-start > 0 ) {
432 | name->assign( start, p-start );
433 | }
434 | return p;
435 | }
436 | return 0;
437 | }
438 |
439 | const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding )
440 | {
441 | // Presume an entity, and pull it out.
442 | TIXML_STRING ent;
443 | int i;
444 | *length = 0;
445 |
446 | if ( *(p+1) && *(p+1) == '#' && *(p+2) )
447 | {
448 | unsigned long ucs = 0;
449 | ptrdiff_t delta = 0;
450 | unsigned mult = 1;
451 |
452 | if ( *(p+2) == 'x' )
453 | {
454 | // Hexadecimal.
455 | if ( !*(p+3) ) return 0;
456 |
457 | const char* q = p+3;
458 | q = strchr( q, ';' );
459 |
460 | if ( !q || !*q ) return 0;
461 |
462 | delta = q-p;
463 | --q;
464 |
465 | while ( *q != 'x' )
466 | {
467 | if ( *q >= '0' && *q <= '9' )
468 | ucs += mult * (*q - '0');
469 | else if ( *q >= 'a' && *q <= 'f' )
470 | ucs += mult * (*q - 'a' + 10);
471 | else if ( *q >= 'A' && *q <= 'F' )
472 | ucs += mult * (*q - 'A' + 10 );
473 | else
474 | return 0;
475 | mult *= 16;
476 | --q;
477 | }
478 | }
479 | else
480 | {
481 | // Decimal.
482 | if ( !*(p+2) ) return 0;
483 |
484 | const char* q = p+2;
485 | q = strchr( q, ';' );
486 |
487 | if ( !q || !*q ) return 0;
488 |
489 | delta = q-p;
490 | --q;
491 |
492 | while ( *q != '#' )
493 | {
494 | if ( *q >= '0' && *q <= '9' )
495 | ucs += mult * (*q - '0');
496 | else
497 | return 0;
498 | mult *= 10;
499 | --q;
500 | }
501 | }
502 | if ( encoding == TIXML_ENCODING_UTF8 )
503 | {
504 | // convert the UCS to UTF-8
505 | ConvertUTF32ToUTF8( ucs, value, length );
506 | }
507 | else
508 | {
509 | *value = (char)ucs;
510 | *length = 1;
511 | }
512 | return p + delta + 1;
513 | }
514 |
515 | // Now try to match it.
516 | for( i=0; iappend( cArr, len );
595 | }
596 | }
597 | else
598 | {
599 | bool whitespace = false;
600 |
601 | // Remove leading white space:
602 | p = SkipWhiteSpace( p, encoding );
603 | while ( p && *p
604 | && !StringEqual( p, endTag, caseInsensitive, encoding ) )
605 | {
606 | if ( *p == '\r' || *p == '\n' )
607 | {
608 | whitespace = true;
609 | ++p;
610 | }
611 | else if ( IsWhiteSpace( *p ) )
612 | {
613 | whitespace = true;
614 | ++p;
615 | }
616 | else
617 | {
618 | // If we've found whitespace, add it before the
619 | // new character. Any whitespace just becomes a space.
620 | if ( whitespace )
621 | {
622 | (*text) += ' ';
623 | whitespace = false;
624 | }
625 | int len;
626 | char cArr[4] = { 0, 0, 0, 0 };
627 | p = GetChar( p, cArr, &len, encoding );
628 | if ( len == 1 )
629 | (*text) += cArr[0]; // more efficient
630 | else
631 | text->append( cArr, len );
632 | }
633 | }
634 | }
635 | if ( p )
636 | p += strlen( endTag );
637 | return p;
638 | }
639 |
640 | #ifdef TIXML_USE_STL
641 |
642 | void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
643 | {
644 | // The basic issue with a document is that we don't know what we're
645 | // streaming. Read something presumed to be a tag (and hope), then
646 | // identify it, and call the appropriate stream method on the tag.
647 | //
648 | // This "pre-streaming" will never read the closing ">" so the
649 | // sub-tag can orient itself.
650 |
651 | if ( !StreamTo( in, '<', tag ) )
652 | {
653 | SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
654 | return;
655 | }
656 |
657 | while ( in->good() )
658 | {
659 | int tagIndex = (int) tag->length();
660 | while ( in->good() && in->peek() != '>' )
661 | {
662 | int c = in->get();
663 | if ( c <= 0 )
664 | {
665 | SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
666 | break;
667 | }
668 | (*tag) += (char) c;
669 | }
670 |
671 | if ( in->good() )
672 | {
673 | // We now have something we presume to be a node of
674 | // some sort. Identify it, and call the node to
675 | // continue streaming.
676 | TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
677 |
678 | if ( node )
679 | {
680 | node->StreamIn( in, tag );
681 | bool isElement = node->ToElement() != 0;
682 | delete node;
683 | node = 0;
684 |
685 | // If this is the root element, we're done. Parsing will be
686 | // done by the >> operator.
687 | if ( isElement )
688 | {
689 | return;
690 | }
691 | }
692 | else
693 | {
694 | SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
695 | return;
696 | }
697 | }
698 | }
699 | // We should have returned sooner.
700 | SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
701 | }
702 |
703 | #endif
704 |
705 | const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding )
706 | {
707 | ClearError();
708 |
709 | // Parse away, at the document level. Since a document
710 | // contains nothing but other tags, most of what happens
711 | // here is skipping white space.
712 | if ( !p || !*p )
713 | {
714 | SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
715 | return 0;
716 | }
717 |
718 | // Note that, for a document, this needs to come
719 | // before the while space skip, so that parsing
720 | // starts from the pointer we are given.
721 | location.Clear();
722 | if ( prevData )
723 | {
724 | location.row = prevData->cursor.row;
725 | location.col = prevData->cursor.col;
726 | }
727 | else
728 | {
729 | location.row = 0;
730 | location.col = 0;
731 | }
732 | TiXmlParsingData data( p, TabSize(), location.row, location.col );
733 | location = data.Cursor();
734 |
735 | if ( encoding == TIXML_ENCODING_UNKNOWN )
736 | {
737 | // Check for the Microsoft UTF-8 lead bytes.
738 | const unsigned char* pU = (const unsigned char*)p;
739 | if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0
740 | && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1
741 | && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 )
742 | {
743 | encoding = TIXML_ENCODING_UTF8;
744 | useMicrosoftBOM = true;
745 | }
746 | }
747 |
748 | p = SkipWhiteSpace( p, encoding );
749 | if ( !p )
750 | {
751 | SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
752 | return 0;
753 | }
754 |
755 | while ( p && *p )
756 | {
757 | TiXmlNode* node = Identify( p, encoding );
758 | if ( node )
759 | {
760 | p = node->Parse( p, &data, encoding );
761 | LinkEndChild( node );
762 | }
763 | else
764 | {
765 | break;
766 | }
767 |
768 | // Did we get encoding info?
769 | if ( encoding == TIXML_ENCODING_UNKNOWN
770 | && node->ToDeclaration() )
771 | {
772 | TiXmlDeclaration* dec = node->ToDeclaration();
773 | const char* enc = dec->Encoding();
774 | assert( enc );
775 |
776 | if ( *enc == 0 )
777 | encoding = TIXML_ENCODING_UTF8;
778 | else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
779 | encoding = TIXML_ENCODING_UTF8;
780 | else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
781 | encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice
782 | else
783 | encoding = TIXML_ENCODING_LEGACY;
784 | }
785 |
786 | p = SkipWhiteSpace( p, encoding );
787 | }
788 |
789 | // Was this empty?
790 | if ( !firstChild ) {
791 | SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding );
792 | return 0;
793 | }
794 |
795 | // All is well.
796 | return p;
797 | }
798 |
799 | void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
800 | {
801 | // The first error in a chain is more accurate - don't set again!
802 | if ( error )
803 | return;
804 |
805 | assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
806 | error = true;
807 | errorId = err;
808 | errorDesc = errorString[ errorId ];
809 |
810 | errorLocation.Clear();
811 | if ( pError && data )
812 | {
813 | data->Stamp( pError, encoding );
814 | errorLocation = data->Cursor();
815 | }
816 | }
817 |
818 |
819 | TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
820 | {
821 | TiXmlNode* returnNode = 0;
822 |
823 | p = SkipWhiteSpace( p, encoding );
824 | if( !p || !*p || *p != '<' )
825 | {
826 | return 0;
827 | }
828 |
829 | TiXmlDocument* doc = GetDocument();
830 | p = SkipWhiteSpace( p, encoding );
831 |
832 | if ( !p || !*p )
833 | {
834 | return 0;
835 | }
836 |
837 | // What is this thing?
838 | // - Elements start with a letter or underscore, but xml is reserved.
839 | // - Comments: ";
1346 |
1347 | if ( !StringEqual( p, startTag, false, encoding ) )
1348 | {
1349 | document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
1350 | return 0;
1351 | }
1352 | p += strlen( startTag );
1353 | p = ReadText( p, &value, false, endTag, false, encoding );
1354 | return p;
1355 | }
1356 |
1357 |
1358 | const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
1359 | {
1360 | p = SkipWhiteSpace( p, encoding );
1361 | if ( !p || !*p ) return 0;
1362 |
1363 | // int tabsize = 4;
1364 | // if ( document )
1365 | // tabsize = document->TabSize();
1366 |
1367 | if ( data )
1368 | {
1369 | data->Stamp( p, encoding );
1370 | location = data->Cursor();
1371 | }
1372 | // Read the name, the '=' and the value.
1373 | const char* pErr = p;
1374 | p = ReadName( p, &name, encoding );
1375 | if ( !p || !*p )
1376 | {
1377 | if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
1378 | return 0;
1379 | }
1380 | p = SkipWhiteSpace( p, encoding );
1381 | if ( !p || !*p || *p != '=' )
1382 | {
1383 | if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
1384 | return 0;
1385 | }
1386 |
1387 | ++p; // skip '='
1388 | p = SkipWhiteSpace( p, encoding );
1389 | if ( !p || !*p )
1390 | {
1391 | if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
1392 | return 0;
1393 | }
1394 |
1395 | const char* end;
1396 | const char SINGLE_QUOTE = '\'';
1397 | const char DOUBLE_QUOTE = '\"';
1398 |
1399 | if ( *p == SINGLE_QUOTE )
1400 | {
1401 | ++p;
1402 | end = "\'"; // single quote in string
1403 | p = ReadText( p, &value, false, end, false, encoding );
1404 | }
1405 | else if ( *p == DOUBLE_QUOTE )
1406 | {
1407 | ++p;
1408 | end = "\""; // double quote in string
1409 | p = ReadText( p, &value, false, end, false, encoding );
1410 | }
1411 | else
1412 | {
1413 | // All attribute values should be in single or double quotes.
1414 | // But this is such a common error that the parser will try
1415 | // its best, even without them.
1416 | value = "";
1417 | while ( p && *p // existence
1418 | && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace
1419 | && *p != '/' && *p != '>' ) // tag end
1420 | {
1421 | if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
1422 | // [ 1451649 ] Attribute values with trailing quotes not handled correctly
1423 | // We did not have an opening quote but seem to have a
1424 | // closing one. Give up and throw an error.
1425 | if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
1426 | return 0;
1427 | }
1428 | value += *p;
1429 | ++p;
1430 | }
1431 | }
1432 | return p;
1433 | }
1434 |
1435 | #ifdef TIXML_USE_STL
1436 | void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
1437 | {
1438 | while ( in->good() )
1439 | {
1440 | int c = in->peek();
1441 | if ( !cdata && (c == '<' ) )
1442 | {
1443 | return;
1444 | }
1445 | if ( c <= 0 )
1446 | {
1447 | TiXmlDocument* document = GetDocument();
1448 | if ( document )
1449 | document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
1450 | return;
1451 | }
1452 |
1453 | (*tag) += (char) c;
1454 | in->get(); // "commits" the peek made above
1455 |
1456 | if ( cdata && c == '>' && tag->size() >= 3 ) {
1457 | size_t len = tag->size();
1458 | if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) {
1459 | // terminator of cdata.
1460 | return;
1461 | }
1462 | }
1463 | }
1464 | }
1465 | #endif
1466 |
1467 | const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
1468 | {
1469 | value = "";
1470 | TiXmlDocument* document = GetDocument();
1471 |
1472 | if ( data )
1473 | {
1474 | data->Stamp( p, encoding );
1475 | location = data->Cursor();
1476 | }
1477 |
1478 | const char* const startTag = "";
1480 |
1481 | if ( cdata || StringEqual( p, startTag, false, encoding ) )
1482 | {
1483 | cdata = true;
1484 |
1485 | if ( !StringEqual( p, startTag, false, encoding ) )
1486 | {
1487 | document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding );
1488 | return 0;
1489 | }
1490 | p += strlen( startTag );
1491 |
1492 | // Keep all the white space, ignore the encoding, etc.
1493 | while ( p && *p
1494 | && !StringEqual( p, endTag, false, encoding )
1495 | )
1496 | {
1497 | value += *p;
1498 | ++p;
1499 | }
1500 |
1501 | TIXML_STRING dummy;
1502 | p = ReadText( p, &dummy, false, endTag, false, encoding );
1503 | return p;
1504 | }
1505 | else
1506 | {
1507 | bool ignoreWhite = true;
1508 |
1509 | const char* end = "<";
1510 | p = ReadText( p, &value, ignoreWhite, end, false, encoding );
1511 | if ( p )
1512 | return p-1; // don't truncate the '<'
1513 | return 0;
1514 | }
1515 | }
1516 |
1517 | #ifdef TIXML_USE_STL
1518 | void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag )
1519 | {
1520 | while ( in->good() )
1521 | {
1522 | int c = in->get();
1523 | if ( c <= 0 )
1524 | {
1525 | TiXmlDocument* document = GetDocument();
1526 | if ( document )
1527 | document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
1528 | return;
1529 | }
1530 | (*tag) += (char) c;
1531 |
1532 | if ( c == '>' )
1533 | {
1534 | // All is well.
1535 | return;
1536 | }
1537 | }
1538 | }
1539 | #endif
1540 |
1541 | const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
1542 | {
1543 | p = SkipWhiteSpace( p, _encoding );
1544 | // Find the beginning, find the end, and look for
1545 | // the stuff in-between.
1546 | TiXmlDocument* document = GetDocument();
1547 | if ( !p || !*p || !StringEqual( p, "SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
1550 | return 0;
1551 | }
1552 | if ( data )
1553 | {
1554 | data->Stamp( p, _encoding );
1555 | location = data->Cursor();
1556 | }
1557 | p += 5;
1558 |
1559 | version = "";
1560 | encoding = "";
1561 | standalone = "";
1562 |
1563 | while ( p && *p )
1564 | {
1565 | if ( *p == '>' )
1566 | {
1567 | ++p;
1568 | return p;
1569 | }
1570 |
1571 | p = SkipWhiteSpace( p, _encoding );
1572 | if ( StringEqual( p, "version", true, _encoding ) )
1573 | {
1574 | TiXmlAttribute attrib;
1575 | p = attrib.Parse( p, data, _encoding );
1576 | version = attrib.Value();
1577 | }
1578 | else if ( StringEqual( p, "encoding", true, _encoding ) )
1579 | {
1580 | TiXmlAttribute attrib;
1581 | p = attrib.Parse( p, data, _encoding );
1582 | encoding = attrib.Value();
1583 | }
1584 | else if ( StringEqual( p, "standalone", true, _encoding ) )
1585 | {
1586 | TiXmlAttribute attrib;
1587 | p = attrib.Parse( p, data, _encoding );
1588 | standalone = attrib.Value();
1589 | }
1590 | else
1591 | {
1592 | // Read over whatever it is.
1593 | while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
1594 | ++p;
1595 | }
1596 | }
1597 | return 0;
1598 | }
1599 |
1600 | bool TiXmlText::Blank() const
1601 | {
1602 | for ( unsigned i=0; i
2 |
3 | success
4 |
5 |
6 | 114148
7 | Jim Berets
8 | VP, Product Management, Black Duck. I'm responsible for openhub.net as well as Black Duck's enterprise products. If you have any questions, comments, or concerns regarding Open Hub, please post them on our forum or email us at info@openhub.net.
9 | jberets
10 | 2010-10-06T16:15:18Z
11 | 2013-07-10T19:20:03Z
12 | http://www.blackducksoftware.com
13 | jberets
14 | https://www.openhub.net/accounts/jberets.xml
15 | https://www.openhub.net/accounts/jberets
16 | http://www.gravatar.com/avatar.php?gravatar_id=a444dc76772d5e41bb2a5df997163123
17 | ddb45a02aab29ac46a9a1fa5740a1ea2e2b183a0
18 | 0
19 | Burlington, MA, USA
20 | US
21 | 42.5047161
22 | -71.1956205
23 |
24 | 1
25 | 670286
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/examples/ApiExample.java:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2013 Black Duck Software, Inc.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
24 | This is an example of using the Open Hub API from Java.
25 | Detailed information can be found at the Open Hub website:
26 |
27 | https://github.com/blackducksoftware/ohloh_api
28 |
29 | This examples retrieves a account and simply shows the name associated.
30 |
31 | Pass your Open Hub API key as the first parameter to this example.
32 | Open Hub API keys are free. If you do not have one, you can obtain one
33 | at the Open Hub website:
34 |
35 | https://www.openhub.net/accounts//api_keys/new
36 |
37 | Pass the email address of the account as the second parameter to this script.
38 | */
39 |
40 | import java.net.*;
41 | import java.security.*;
42 | import java.io.*;
43 | import java.util.*;
44 | import org.w3c.dom.*;
45 | import javax.xml.parsers.*;
46 |
47 | public class ApiExample
48 | {
49 | private static final char[] hexChars ={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
50 |
51 | public static void usage()
52 | {
53 | System.out.println("Usage:");
54 | System.out.println("java ApiExample [api_key] [user_email]");
55 | }
56 |
57 | public ApiExample(String apiKey, String userEmail)
58 | {
59 | initiate(apiKey, userEmail);
60 | }
61 |
62 | public void initiate(String apiKey, String userEmail)
63 | {
64 | System.out.println("Initialising request.");
65 |
66 | // Calculate MD5 digest from the email address.
67 | String emailDigest = calculateDigest(userEmail);
68 |
69 | try
70 | {
71 | // Request XML file.
72 | URL url = new URL("https://www.openhub.net/accounts/" + emailDigest + ".xml?api_key=" + apiKey + "&v=1");
73 | URLConnection con = url.openConnection();
74 |
75 | // Check for status OK.
76 | if (con.getHeaderField("Status").startsWith("200"))
77 | {
78 | System.out.println("Request succeeded.");
79 | }
80 | else
81 | {
82 | System.out.println("Request failed. Possibly wrong API key?");
83 | return;
84 | }
85 | System.out.println("Looking up name..");
86 |
87 | // Create a document from the URL's input stream, and parse.
88 | DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
89 | Document doc = builder.parse(con.getInputStream());
90 |
91 | NodeList responseNodes = doc.getElementsByTagName("response");
92 | for (int i = 0; i < responseNodes.getLength(); i++)
93 | {
94 | Element element = (Element)responseNodes.item(i);
95 |
96 | // First check for the status code inside the XML file. It is
97 | // most likely, though, that if the request would have failed,
98 | // it is already returned earlier.
99 | NodeList statusList = element.getElementsByTagName("status");
100 | if (statusList.getLength() == 1)
101 | {
102 | Node statusNode = statusList.item(0);
103 |
104 | // Check if the text inidicates that the request was
105 | // successful.
106 | if (!statusNode.getTextContent().equals("success"))
107 | {
108 | System.out.println("Failed. " + statusNode.getTextContent());
109 | return;
110 | }
111 | }
112 |
113 | Element resultElement = (Element)element.getElementsByTagName("result").item(0);
114 | // We assume we only have one account result here.
115 | Element accountElement = (Element)resultElement.getElementsByTagName("account").item(0);
116 |
117 | if (accountElement != null)
118 | {
119 | // Lookup name.
120 | String realName = accountElement.getElementsByTagName("name").item(0).getTextContent();
121 | System.out.println("Located the real name: " + realName);
122 | }
123 | }
124 | }
125 | catch (Exception e)
126 | {
127 | e.printStackTrace();
128 | }
129 | }
130 |
131 | public String calculateDigest(String email)
132 | {
133 | return hexStringFromBytes(calculateHash(email.getBytes()));
134 | }
135 |
136 | private byte[] calculateHash(byte[] dataToHash)
137 | {
138 | try
139 | {
140 | // Calculate MD5 digest.
141 | MessageDigest md = MessageDigest.getInstance("MD5");
142 | md.update(dataToHash, 0, dataToHash.length);
143 | return md.digest();
144 | }
145 | catch (NoSuchAlgorithmException e)
146 | {
147 | e.printStackTrace();
148 | }
149 | return null;
150 | }
151 |
152 | public String hexStringFromBytes(byte[] b)
153 | {
154 | // Conversion from bytes to String.
155 | String hex = "";
156 |
157 | int msb;
158 |
159 | int lsb = 0;
160 | int i;
161 |
162 | for (i = 0; i < b.length; i++)
163 | {
164 | msb = ((int)b[i] & 0x000000FF) / 16;
165 |
166 | lsb = ((int)b[i] & 0x000000FF) % 16;
167 | hex = hex + hexChars[msb] + hexChars[lsb];
168 | }
169 | return hex;
170 | }
171 |
172 | public static void main(String[] args)
173 | {
174 | if (args.length == 2)
175 | {
176 | // Simply pass arguments.
177 | new ApiExample(args[0], args[1]);
178 | }
179 | else
180 | {
181 | // Show usage information.
182 | usage();
183 | }
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | ## Open Hub API Examples #
2 | Some basic [Open Hub](https://www.openhub.net) API samples to help you get started. For information on the Open Hub API, please see the [documentation](/README.md). The Open Hub API has some restrictions, so please review the complete [Terms of Use](http://blog.openhub.net/terms-2) before you begin.
3 |
4 | ### Examples are available in: ###
5 | * BASH
6 |
7 | Uses `curl` to pull an [Account](/reference/account.md) from Open Hub and `openssl` to create MD5 hex of the email address. A simple sed hack parses the XML response into name:value pairs. The example demonstrates data retrieval using email address lookup. Pass your API key and the email address of the Account you are requsting as parameters to the script:
8 |
9 | `./account_sample.sh YOUR_API_KEY_HERE rluckey@blackducksoftware.com`
10 |
11 | The script isn’t very robust — `sed` is not the world’s best XML parser — but it does return a non-zero exit code if the record is not found or some other problem occurs.
12 |
13 | * Ruby
14 |
15 | Performs the same email-based account lookup, but uses more rigorous error handling and parsing to create a structured XML document object. Using the `REXML` library, you can build a more robust interface to the Open Hub API.
16 |
17 | Execute the script by passing your API key and an email address as parameters:
18 |
19 | `ruby account_sample.rb YOUR_API_KEY_HERE rluckey@blackducksoftware.com`
20 |
21 | * Python
22 |
23 | Performs a similar account lookup on Open Hub. It requires `urllib`, `hashlib` and `elementtree`.
24 |
25 | Execute the script by passing your API key and an email address as parameters:
26 |
27 | `./account_sample.py YOUR_API_KEY_HERE rluckey@blackducksoftware.com`
28 |
29 | Many thanks to [Thijs Triemstra](https://www.openhub.net/accounts/3953) for contributing this sample.
30 |
31 | * Perl
32 |
33 | Performs a similar account lookup on Open Hub. It requires the `LWP::Simple`, `Digest::MD5`, and `XML::Simple` libraries.
34 |
35 | Execute the script by passing your API key and an email address as parameters:
36 |
37 | `./account_sample.pl YOUR_API_KEY_HERE rluckey@blackducksoftware.com`
38 |
39 | Many thanks to [Yanick Champoux](https://www.openhub.net/accounts/12933) for contributing this sample.
40 |
41 | * Java
42 |
43 | Uses Java’s networking capabilities to pull an [Account](/reference/account.md) from Open Hub. It demonstrates how to generate an MD5 hash of an email address to use as a lookup key, then uses DOM to parse the XML response.
44 |
45 | Pass your API key and the email address of the Account you are requesting as parameters:
46 |
47 | `javac ApiExample.java`
48 |
49 | `java ApiExample YOUR_API_KEY_HERE rluckey@blackducksoftware.com`
50 |
51 | * C++
52 |
53 | The C++ example is a bit more involved, because it must include code for networking, MD5 hashing, and XML parsing. The example includes source for some small libraries to create a self-contained program.
54 |
55 | The code was written for Visual Studio 2005, but it also compiles and runs on Mac OS X, and should work on Linux. Let us know if you encounter trouble on your platform.
56 |
57 | To build with Visual Studio 2005:
58 | * Open solution file `ApiExample.cpp/build/vs2005/ohlohExample.sln`
59 | * Right-click the solution and choose *Build*.
60 |
61 | To build on Linux or Mac OS X, *cd to ApiExample.cpp* and run the build script:
62 |
63 | `./compile.sh`
64 |
65 | You can then run the executable called `ApiExample` and pass it your API key and an email address:
66 |
67 | `./bin/ApiExample YOUR_API_KEY_HERE rluckey@blackducksoftware.com`
68 |
69 | Many thanks to [Lars ‘Levia’ Wesselius](https://www.openhub.net/accounts/739) for providing the sample code in both C++ and Java!
70 |
71 | * PHP
72 |
73 | Paul Scott has created a full-featured PHP class for accessing the Open Hub API, complete with documentation. You can find it at the [PHP Classes](http://www.phpclasses.org/browse/package/4261.html) website.
74 |
75 |
76 | Your feedback on these examples will benefit everyone, and we’re eager for input on improvements.
77 | We’d also appreciate help translating the samples into more languages.
78 |
79 | Please don’t hesitate to contact us at info@openhub.net.
80 |
--------------------------------------------------------------------------------
/examples/account_sample.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/perl
2 |
3 | =pod
4 |
5 | =head1 NAME
6 |
7 | account_sample.pl - Simple example of using the Open Hub API from Perl
8 |
9 | =head1 SYNOPSIS
10 |
11 | account_sample.pl api_key email
12 |
13 | =head1 DESCRIPTION
14 |
15 | This is a small example of how to use the Open Hub API from Perl,
16 | mimicking the Ruby example - account_sample.rb
17 |
18 | Detailed information about the Open Hub API can be found at
19 | https://github.com/blackducksoftware/ohloh_api
20 |
21 | The script takes an API key and the email address of a developer
22 | registered on Open Hub as parameters, and prints out all the
23 | information of that account.
24 |
25 | =head1 EXAMPLE
26 |
27 | ./account_sample.pl YOUR_API_KEY_HERE robin@openhub.net
28 |
29 | =head1 DEPENDENCIES
30 |
31 | This script uses
32 | L (to query the Open Hub website),
33 | L (to MD5s the email address as requested by the API)
34 | and
35 | L (to parse the server's answer).
36 |
37 | =head1 VERSION
38 |
39 | This documentation refers to account_sample version 0.1
40 |
41 | =head1 AUTHOR
42 |
43 | Yanick Champoux (yanick@cpan.org)
44 |
45 | =head1 LICENCE AND COPYRIGHT
46 |
47 | Copyright (c) 2007 Yanick Champoux (yanick@cpan.org). All rights reserved.
48 |
49 | This module is free software; you can redistribute it and/or
50 | modify it under the same terms as Perl itself. See perldoc perlartistic.
51 |
52 | This program is distributed in the hope that it will be useful,
53 | but WITHOUT ANY WARRANTY; without even the implied warranty of
54 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
55 |
56 | =cut
57 |
58 | use strict;
59 | use warnings;
60 |
61 | use LWP::Simple;
62 | use Digest::MD5 qw/ md5_hex /;
63 | use XML::Simple;
64 |
65 | my $VERSION = '0.01';
66 | my $API_VERSION = 1;
67 |
68 | die_usage() unless @ARGV == 2;
69 |
70 | my ( $api_key, $email ) = @ARGV;
71 |
72 | my $email_md5 = md5_hex($email);
73 |
74 | ### let's build the request url
75 | # first the base url
76 | my $url = 'https://www.openhub.net/';
77 | # then the email "page" we want
78 | $url .= "accounts/$email_md5.xml";
79 | # and finally the API version and the api key
80 | $url .= '?' . join '&' => "v=$API_VERSION", "api_key=$api_key";
81 |
82 | # request the url from the server
83 | my $response = get $url or die "Open Hub server didn't return anything\n";
84 |
85 | # parse the XML response
86 | my $xml = eval { XMLin($response) } or die "Server didn't return valid XML\n";
87 |
88 | # was the request a success?
89 | die "request didn't succeed: $xml->{error}\n"
90 | unless $xml->{status} eq 'success';
91 |
92 | # make an alias to the info we want
93 | my %account = %{ $xml->{result}{account} };
94 |
95 | # now we print the info for the account
96 |
97 | for my $attr (
98 | qw/ id name created_at updated_at homepage_url
99 | avatar_url posts_count location country_code
100 | latitude longitude /
101 | ) {
102 |
103 | # only print the attribute if it exist
104 | printf "%-20s: %s\n", $attr, $account{$attr}
105 | if defined $account{$attr} and not ref $account{$attr};
106 | }
107 |
108 | # print the kudo information
109 | printf "%-20s: %s\n", 'kudo rank', $account{kudo_score}{kudo_rank}
110 | if $account{kudo_score};
111 |
112 | exit;
113 |
114 | ### utility functions ######################################
115 |
116 | sub die_usage {
117 | die "usage: $0 api_key email\n";
118 | }
119 |
120 | __END__
121 |
--------------------------------------------------------------------------------
/examples/account_sample.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | """
4 | The MIT License (MIT)
5 |
6 | Copyright (c) 2013 Thijs Triemstra
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 | """
26 |
27 | """
28 | This is an example of using the Open Hub API from Python.
29 |
30 | Detailed information can be found on GitHub:
31 |
32 | https://github.com/blackducksoftware/ohloh_api
33 |
34 | This example uses the ElementTree library for XML parsing
35 | (included in Python 2.5 and newer):
36 |
37 | http://effbot.org/zone/element-index.htm
38 |
39 | This example retrieves basic Open Hub account information
40 | and outputs it as simple name: value pairs.
41 |
42 | Pass your Open Hub API key as the first parameter to this script.
43 | Open Hub API keys are free. If you do not have one, you can obtain one
44 | at the Open Hub website:
45 |
46 | https://www.openhub.net/accounts//api_keys/new
47 |
48 | Pass the email address of the account as the second parameter to this script.
49 | """
50 |
51 | import sys, urllib, hashlib
52 | # import ElementTree based on the python version
53 | try:
54 | import elementtree.ElementTree as ET
55 | except ImportError:
56 | import xml.etree.ElementTree as ET
57 |
58 | # We pass the MD5 hash of the email address
59 | email = hashlib.md5()
60 | email.update(sys.argv[2])
61 |
62 | # Connect to the Open Hub website and retrieve the account data.
63 | params = urllib.urlencode({'api_key': sys.argv[1], 'v': 1})
64 | url = "https://www.openhub.net/accounts/%s.xml?%s" % (email.hexdigest(), params)
65 | f = urllib.urlopen(url)
66 |
67 | # Parse the response into a structured XML object
68 | tree = ET.parse(f)
69 |
70 | # Did Open Hub return an error?
71 | elem = tree.getroot()
72 | error = elem.find("error")
73 | if error != None:
74 | print 'Open Hub returned:', ET.tostring(error),
75 | sys.exit()
76 |
77 | # Output all the immediate child properties of an Account
78 | for node in elem.find("result/account"):
79 | if node.tag == "kudo_score":
80 | print "%s:" % node.tag
81 | for score in elem.find("result/account/kudo_score"):
82 | print "\t%s:\t%s" % (score.tag, score.text)
83 | else:
84 | print "%s:\t%s" % (node.tag, node.text)
85 |
--------------------------------------------------------------------------------
/examples/account_sample.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'net/https'
3 | require 'rexml/document'
4 | require 'digest/md5'
5 |
6 | # The MIT License (MIT)
7 | #
8 | # Copyright (c) 2013 Black Duck Software, Inc.
9 | #
10 | # Permission is hereby granted, free of charge, to any person obtaining a copy
11 | # of this software and associated documentation files (the "Software"), to deal
12 | # in the Software without restriction, including without limitation the rights
13 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | # copies of the Software, and to permit persons to whom the Software is
15 | # furnished to do so, subject to the following conditions:
16 | #
17 | # The above copyright notice and this permission notice shall be included in
18 | # all copies or substantial portions of the Software.
19 | #
20 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 | # THE SOFTWARE.
27 |
28 | # This is an example of using the Open Hub API from Ruby.
29 | # Detailed information can be found at the Open Hub website:
30 | #
31 | # https://github.com/blackducksoftware/ohloh_api
32 | #
33 | # This example uses the REXML library for XML parsing:
34 | #
35 | # http://www.germane-software.com/software/rexml/
36 | #
37 |
38 | # This example retrieves basic Open Hub account information
39 | # and outputs it as simple name: value pairs.
40 | #
41 | # Pass your Open Hub API key as the first parameter to this script.
42 | # Open Hub API keys are free. If you do not have one, you can obtain one
43 | # at the Open Hub website:
44 | #
45 | # https://www.openhub.net/accounts//api_keys/new
46 | #
47 | # Pass the email address of the account as the second parameter to this script.
48 |
49 | unless ARGV[0] =~ /[\w]+/ and ARGV[1] =~ /.+@.+\..+/
50 | STDERR.puts "Usage: #{__FILE__} [api_key] [email]"
51 | exit 1
52 | end
53 |
54 | api_key = ARGV[0]
55 | email = ARGV[1]
56 |
57 | #
58 | # Connect to the Open Hub website and retrieve the account data.
59 | #
60 |
61 | # We pass the MD5 hash of the email address
62 | email_md5 = Digest::MD5.hexdigest(email).to_s
63 |
64 | uri = URI("https://www.openhub.net/accounts/#{email_md5}.xml?v=1&api_key=#{api_key}")
65 | http = Net::HTTP.new(uri.host, uri.port)
66 | http.use_ssl = true
67 | response = http.get(uri.request_uri)
68 |
69 | # HTTP OK?
70 | if response.code != '200'
71 | STDERR.puts "#{response.code} - #{response.message}"
72 | exit 1
73 | end
74 |
75 | # Parse the response into a structured XML object
76 | xml = REXML::Document.new(response.body)
77 |
78 | # Did Open Hub return an error?
79 | error = xml.root.get_elements('/response/error').first
80 | if error
81 | STDERR.puts "#{error.text}"
82 | exit 1
83 | end
84 |
85 | # Output all the immediate child properties of an Account
86 | xml.root.get_elements('/response/result/account').first.each_element do |element|
87 | puts "#{element.name}:\t#{element.text}" unless element.has_elements?
88 | end
89 |
90 | # The kudo_rank element may not be present.
91 | # Check for it, and default to 1 if it is missing.
92 | xml_kudo_rank = xml.root.get_elements('/response/result/account/kudo_score/kudo_rank').first
93 | kudo_rank = xml_kudo_rank ? xml_kudo_rank.text.to_i : 1
94 | puts "kudo_rank:\t#{kudo_rank}"
95 |
--------------------------------------------------------------------------------
/examples/account_sample.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # The MIT License (MIT)
4 | #
5 | # Copyright (c) 2013 Black Duck Software, Inc.
6 | #
7 | # Permission is hereby granted, free of charge, to any person obtaining a copy
8 | # of this software and associated documentation files (the "Software"), to deal
9 | # in the Software without restriction, including without limitation the rights
10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | # copies of the Software, and to permit persons to whom the Software is
12 | # furnished to do so, subject to the following conditions:
13 | #
14 | # The above copyright notice and this permission notice shall be included in
15 | # all copies or substantial portions of the Software.
16 | #
17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | # THE SOFTWARE.
24 |
25 | # This is an example of using the Open Hub API from Bash.
26 | # Detailed information can be found on GitHub:
27 | #
28 | # https://github.com/blackducksoftware/ohloh_api
29 | #
30 |
31 | # This example retrieves basic Open Hub account information
32 | # and outputs it as simple name: value pairs.
33 | #
34 | # Pass your Open Hub API key as the first parameter to this script.
35 | # Open Hub API keys are free. If you do not have one, you can obtain one
36 | # at the Open Hub website:
37 | #
38 | # https://www.openhub.net/accounts//api_keys/new
39 | #
40 | # Pass the email address of the account as the second parameter to this script.
41 |
42 | usage() {
43 | echo >&2 "Usage: $0 [api_key] [email]"
44 | exit 1
45 | }
46 |
47 | echo $1 | grep -q -E -e'.+' || usage
48 | API_KEY=$1
49 |
50 | echo $2 | grep -q -E -e'.+@.+\..+' || usage
51 | EMAIL_MD5=`echo -n $2 | openssl md5 | cut -f2 -d" "`
52 |
53 | # Pass the MD5 hash of the email address to Open Hub.
54 | # A quick-and-dirty sed filter converts the XML response to name:value pairs
55 | #
56 | # We use the --fail option so that curl will return a non-zero exit status if Open Hub returns an error.
57 | # This also means that the error message text returned from Open Hub will be suppressed from the output.
58 | curl --fail -s "https://www.openhub.net/accounts/$EMAIL_MD5.xml?v=1&api_key=$API_KEY" | sed -n 's/ *<\(.*\)>\(.*\)<\/\1>$/\1: \2/ p'
59 |
60 | # Forward along the exit status from curl
61 | exit $PIPESTATUS
62 |
--------------------------------------------------------------------------------
/examples/oauth2/README.md:
--------------------------------------------------------------------------------
1 | ## Using OAuth 2.0 with the Open Hub API
2 |
3 | ### What is OAuth 2.0?
4 |
5 | [OAuth 2.0](http://oauth.net/2) is the next evolution of the OAuth protocol. It is an open protocol that allows applications and websites to share sensitive data, without requiring you to release your password. Using OAuth, you can permit third-party applications to read from your Open Hub account without having to share your password.
6 |
7 | Instead of handing out your Open Hub account password to a third-party application, you visit the Open Hub website directly and grant that application permission to access your Open Hub account. You can revoke this permission any time you change your mind.
8 |
9 | ### Using OAuth 2.0
10 |
11 | In order to become Open Hub OAuth consumer, you'd need to get your key and secret from your [API Keys](https://www.openhub.net/accounts/me/api_keys) page.
12 |
13 | The application [ohloh_oauth2_sinatra.rb](/examples/oauth2/ohloh_oauth2_sinatra.rb) is a simple [Sinatra](http://www.sinatrarb.com/) based example using the [oauth2 gem](https://github.com/intridea/oauth2) that fetches authenticated user's [account](/reference/account.md) xml.
14 |
15 | ### Developer Information
16 |
17 | OAuth 2.0 is an optional, additional feature of the Open Hub API that can be used to integrate Open Hub users on your website using their authenticated identity. You can read public data from Open Hub at any time using only your application’s Open Hub API Key.
18 |
--------------------------------------------------------------------------------
/examples/oauth2/ohloh_oauth2_sinatra.rb:
--------------------------------------------------------------------------------
1 | require 'oauth2'
2 | require 'sinatra'
3 |
4 | enable :sessions
5 | CALLBACK_URL = 'http://localhost:9292/callback'
6 |
7 | # Assumes that you have set OpenHub_KEY and OpenHub_SECRET environment
8 | # variables to values from your API keys page.
9 | before do
10 | @client = OAuth2::Client.new(ENV['OpenHub_KEY'], ENV['OpenHub_SECRET'],
11 | site: 'https://www.openhub.net',
12 | token_method: :post)
13 | end
14 |
15 | def access_token
16 | OAuth2::AccessToken.new(@client, session[:access_token], refresh_token: session[:refresh_token])
17 | end
18 |
19 | get '/login' do
20 | redirect @client.auth_code.authorize_url(redirect_uri: CALLBACK_URL)
21 | end
22 |
23 | get '/callback' do
24 | new_token = @client.auth_code.get_token(params[:code], redirect_uri: CALLBACK_URL)
25 | session[:access_token] = new_token.token
26 | session[:refresh_token] = new_token.refresh_token
27 |
28 | access_token.get('accounts/me.xml').body
29 | end
30 |
--------------------------------------------------------------------------------
/reference/account.md:
--------------------------------------------------------------------------------
1 | ## Account
2 |
3 | An Account represents an Open Hub member. Some Account data is private, and cannot be accessed through the Open Hub API.
4 |
5 | ### Properties
6 | + __id__
7 | The unique ID for the Account.
8 |
9 | + __name__
10 | The public name for this Account.
11 |
12 | + __about__
13 | A short description about this account.
14 |
15 | + __login__
16 | The Login handle for this account.
17 |
18 | + __created_at__
19 | The time at which this Account was originally created on Open Hub.
20 |
21 | + __updated_at__
22 | The time at which this Account record was last modified.
23 |
24 | + __homepage_url__
25 | An optional URL to a member’s home page, such as a blog.
26 |
27 | + __twitter_account__
28 | An optional Twitter handle for this account.
29 |
30 | + __url__
31 | A URL, returning details about this account in XML format.
32 |
33 | + __html_url__
34 | A URL to the profile's Home page for this account.
35 |
36 | + __avatar_url__
37 | A URL to the profile image displayed on Open Hub pages. Currently, this is an URL to the Gravatar free image hosting service, which will resolves to a default image if the account holder is not a Gravatar member. Images are 80×80 by default.
38 |
39 | + __email_sha1__
40 | The SHA1 hex digest of the account email address.
41 |
42 | + __posts_count__
43 | The number of posts made to the Open Hub forums by this account.
44 |
45 | + __location__
46 | An optional text description of this account holder’s claimed location. This text has been validated by either the Google or Yahoo geocoder web service, but the precision is variable.
47 |
48 | + __country_code__
49 | A string representing the account holder’s country. This field is derived from location using either the Google or Yahoo geocoder web service. If you use this data, read the important note below.
50 |
51 | + __latitude__ and __longitude__
52 | Floating-point values representing the account’s latitude and longitude, suitable for use with the Google Maps API. They are available only when the account has specified a valid location.
53 |
54 | + __kudo_score__
55 | If this account has a KudoScore, it will appear here. New accounts may not have a KudoScore. The Open Hub web site displays these accounts with a default KudoRank of 1.
56 |
57 | + __languages__
58 | Only available when requesting an accounts details, this node will not be returned as part of a search result list. This node contains the total language experience for this account grouped by language.Eachnode contains the following children:
59 | - __@color__
60 | This is the Open Hub color code for this language. If you will be displaying this data in your application it is highly recommended you use the colors returned here as these are the same colors Open Hub uses to display specific languages.
61 | - __name__
62 | The Open Hub code name for this language, e.g. C# will be csharp and C++ will be cpp.
63 | - __experience_months__
64 | The total number of months that Open Hub has computed as experience in this language for the current Account.
65 | - __total_commits__
66 | The total number of commits made by the current Account that contained code in the current Language.
67 | - __total_lines_changed__
68 | The total number of lines changed by the current Account that contained code in the current Language.
69 | - __comment_ratio__
70 | The ratio of comment lines to code lines in commits made by the current Account for the current Language.
71 |
72 | ```xml
73 |
74 |
75 | javascript
76 | 24
77 | 116
78 | 563,931
79 | 23.4%
80 |
81 |
82 | css
83 | 20
84 | 83
85 | 74,705
86 | 4.3%
87 |
88 |
89 | html
90 | 19
91 | 62
92 | 27,875
93 | 20.5%
94 |
95 |
96 | ```
97 |
98 | + __badges__
99 | Lists the badges awarded to the account holder. All accounts have a Kudo Score of at least 1, so the Kudo Rank badge will always appear here. Badges are listed with these attributes:
100 | - __name__
101 | The name of the badge
102 | - __level__
103 | The numeric value of the level for the badge. Some badges are "binary", such as the Project Manager or the Organization Manager badges. These are awarded when the account holder manages a project or organization, respectively. For these types of badges, the level is '0'
104 | - __description__
105 | This is the description of the badge that is used for tool tips on Open Hub
106 | - __image_url__
107 | This is the URL of a 64x64 pixel icon of the badge image
108 | - __pips_url__
109 | This is the URL of a 15x64 pixel icon of the pips based on the level. This will be empty when the level is 0.
110 |
111 | ### Making API Calls
112 |
113 | #### Individual account
114 | To get a single Account:
115 | ```shell
116 | curl https://www.openhub.net/accounts/{account_id}.xml
117 | ```
118 |
119 | You can also retrieve an Account using the MD5 hash of the email address, if you know it:
120 | ```shell
121 | curl https://www.openhub.net/accounts/{email_md5_hash}.xml
122 | ```
123 |
124 | Read more about email-based queries [here](/email_lookup.md).
125 |
126 | #### Collection of accounts
127 | To get a list of all Accounts:
128 | ```shell
129 | curl https://www.openhub.net/accounts.xml
130 | ```
131 |
132 | The account collection method supports the standard [collection request parameters](/README.md#collection-requests) with the following details:
133 |
134 | + __query__
135 | If supplied, only accounts matching the query string will be returned. Only the name field is searched.
136 | + __sort__
137 | Account collections support the following sort options:
138 | - __created_at (default)__
139 | Recently created, first
140 | - __name__
141 | - __updated_at__
142 | Recently updated, first
143 |
144 | ### A Note about Country Codes
145 | Open Hub preferentially uses the [Google Maps API](http://www.google.com/apis/maps/documentation/index.html) geocoder to resolve location names entered by users. `country_code` values obtained from the Google Maps API use two-letter abbreviations.
146 |
147 | However, Google’s coverage is not complete, and not all countries can be resolved. For countries that cannot be resolved by the Google geocoder, Open Hub falls back to the Yahoo geocoder. These countries include the United Kingdom and China. `country_code` values obtained from Yahoo are full country names, not two-letter abbreviations.
148 |
149 | For this reason, there are two data formats intermingled in country_code. Open Hub does not use this data internally, so the data has not been cleaned and unified.
150 |
--------------------------------------------------------------------------------
/reference/activity_fact.md:
--------------------------------------------------------------------------------
1 | ## ActivityFact
2 | An ActivityFact is a pre-computed collection of statistics about [Project](/reference/project.md) source code. It summarizes changes to lines of code, commits, and contributors in a single month.
3 |
4 | [SizeFacts](/reference/size_fact.md) contain the running totals of ActivityFacts.
5 |
6 | An ActivityFact is derived from lower-level statistics contained in an [Analysis](/reference/analysis.md). ActivityFacts are updated whenever a [Project](/reference/project.md) is re-analyzed.
7 |
8 | ActivityFacts are availabled only after Open Hub has downloaded and analyzed the project source code.
9 |
10 | ### Properties
11 |
12 | + __month__
13 | Indicates the month covered by this ActivityFact. Only the year and month fields are significant. This ActivityFact record includes all development activity that occured during this month.
14 | + __code_added__
15 | The total new lines of code added, excluding comments and blanks, during this month.
16 | + __code_removed__
17 | The total lines of code removed, excluding comments and blanks, during this month.
18 | + __comments_added__
19 | The total lines of new comments added during this month.
20 | + __comments_removed__
21 | The total lines of comments removed during this month.
22 | + __blanks_added__
23 | The total blank lines added during this month.
24 | + __blanks_removed__
25 | The total blank lines removed during this month.
26 | + __commits__
27 | The number of commits made during this month.
28 | + __contributors__
29 | The number of contributors who made at least one commit during this month.
30 |
31 | ### Collection URL
32 | To get all ActivityFacts for a particular [Analysis](/reference/analysis.md):
33 | ```shell
34 | curl https://www.openhub.net/p/{project_id}/analyses/{analysis_id}/activity_facts.xml
35 | ```
36 | If you do not know the ID of the current best Analysis for a Project, you can use the `latest` as a shortcut for latest published analysis.
37 | ```shell
38 | curl https://www.openhub.net/p/{project_id}/analyses/latest/activity_facts.xml
39 | ```
40 |
41 | The call returns one Activity for each month, starting at the first month in which any code exists, and ending at the current month. If Open Hub has not created a new Analysis for this Project in a long time, the ActivityFacts for the months following the time of the last Analysis will contain zeros.
42 |
43 | The results cannot be paginated or filtered. Results are sorted chronologically.
44 |
--------------------------------------------------------------------------------
/reference/affiliated_committers.md:
--------------------------------------------------------------------------------
1 | ##Affiliated Committers
2 | People that are part of an organization and commit to its projects
3 |
4 |
5 | ### Properties
6 |
7 | + __affiliator__
8 | + __name__ Name of the user account
9 | + __kudos__ Kudos obtained by the user account
10 | + __level__ Level of the user account
11 | + __most_commits__
12 | + __project__ Name of the project to which the committer has made most commits to
13 | + __commits__ No of commits made to the most committed project
14 | + __most_recent_commit__
15 | + __project__ Name of the project last to committed by the affiliator
16 | + __date__ Date of the last commit
17 | + __detailed_page_url__ This page's relative url
18 |
19 |
20 | ### URL
21 |
22 | ```shell
23 | https://www.openhub.net/orgs/{org_name}/affiliated_committers.xml?api_key={api_key}&page={number}
24 | ```
25 |
26 | #### Example
27 |
28 | ```ruby
29 | https://www.openhub.net/orgs/mozilla/affiliated_committers.xml?api_key=some_example_api_key&page=2
30 | ```
31 |
--------------------------------------------------------------------------------
/reference/analysis.md:
--------------------------------------------------------------------------------
1 | ## Analysis
2 |
3 | An Analysis is a pre-computed collection of statistics about [Project](/reference/project.md) source code and contributors.
4 |
5 | An individual Analysis never changes. When a Project’s source code is modified, a completely new Analysis is generated for that Project. Eventually, old analyses are deleted from the database. Therefore, you should always obtain the ID of the best current analysis from the project record before requesting an analysis.
6 |
7 | The Analysis object described here contains only a few top-level metrics. Detailed, historical metrics are contained within child objects of an Analysis, which will be exposed through the API at a later date.
8 |
9 | ### Properties
10 |
11 | + __id__
12 | The unique ID for the Analysis.
13 | + __url__
14 | A URL, returning details about this Analysis in XML format.
15 | + __project_id__
16 | The unique ID of the Project measured by this Analysis.
17 | + __updated_at__
18 | The time at which this Analysis record was last modified.
19 | + __oldest_code_set_time__
20 | The time at which Open Hub queried the source control system for the source code measured by this Analysis. All commits which occured at or before this time are included. Note that the Analysis might also include some activity after this time if the project includes many [Repositories](/reference/repository.md), because not all Repositories are updated at the same time. The logged_at time is the most pessimistic time among all the Repositories included in the Project.
21 | + __min_month__
22 | Open Hub groups most historical statistics ([ActivityFacts](/reference/activity_fact.md) and [SizeFacts](/reference/size_fact.md)) into monthly totals. min_month indicates the first month for which Open Hub has monthly historical statistics available for this project. This is typically the date of the first project commit, truncated to the beginning of its calendar month. Only the year and month fields are significant.
23 | + __max_month__
24 | The last month for which monthly historical statistics are available for this project. Depending on when this analysis was prepared, max_month usually refers to the current month, but it may be slightly older. Only the year and month fields are significant. Open Hub’s monthly statistics for max_month are usually smaller than other months because the complete month has not yet elapsed, and it reflects ongoing development work.
25 | + __twelve_month_contributor_count__
26 | The number of contributors who made at least one commit to the project source code in the twelve months leading up to and including `max_month`.
27 | + __total_contributor_count__
28 | The total number of contributors who made at least one commit to the project source code leading up to and including `max_month`.
29 | + __twelve_month_commit_count__
30 | The number of commits to the project source code in the twelve months leading up to and including `max_month`.
31 | + __total_commit_count__
32 | The total number of commits to the project source code leading up to and including `max_month`.
33 | + __total_code_lines__
34 | The most recent total count of all source code lines. Blank lines and comment lines are excluded.
35 | + __main_language_id__
36 | The unique ID of the most common programming language used in this project. XML and HTML are ignored when making this determination.
37 | + __main_language_name__
38 | The name of the most common programming language used in this project. XML and HTML are ignored when making this determination.
39 | + __factoids__
40 | The factoids for the current Analysis will be included under this node.
41 |
42 | ```xml
43 |
44 | Very large, active development team
45 | Mature, well-established codebase
46 | Increasing year-over-year development activity
47 | Few source code comments
48 |
49 | ```
50 |
51 | + __language__
52 | The language breakdown chart for the current Analysis will be included under this node. The node will have the following children:
53 | - _@graph_url_
54 | This is the url to the PNG image that depicts the language breakdown for the current Analysis. The colors referenced in each languages @color attribute will be used in this image.
55 | - _language_
56 | Not every language will have a entry. Open Hub will will combine languages that do not make up a significant percentage into a aggregate entry “N Other”. This entry can be identified by either its @color, always “000000″ or @id, always “”.
57 | Each language will contain the following data
58 | - @color The color code that Open Hub uses to represent this language on the website. This color is also used in the language breakdown graph image.
59 | - @percentage The percentage of lines of code that the current language represents in the current Analysis
60 | - @id The Open Hub language id.
61 |
62 | ```xml
63 |
64 | C++
65 | C
66 | JavaScript
67 | 28 Other
68 |
69 | ```
70 |
71 |
72 | ### URL
73 | To get a particular Analysis for a single Project:
74 | ```shell
75 | curl https://www.openhub.net/p/{project_id}/analyses/{analysis_id}.xml
76 | ```
77 |
78 | A shortcut to the current best Analysis for a single Project can be made by substituting `latest` for the analysis ID:
79 | ```shell
80 | curl https://www.openhub.net/p/{project_id}/analyses/latest.xml
81 | ```
82 |
--------------------------------------------------------------------------------
/reference/code_location.md:
--------------------------------------------------------------------------------
1 | ## Code Location
2 | A Code Location represents an individual source control repository.
3 |
4 | Once added to the Open Hub database, a Code Location is permanent and unique.
5 |
6 | A Code Location is added to a [Project](project.md) by creating an [Enlistment](enlistment.md), which links the Project to the Code Location. In this way, many Projects can share the same Code Location.
7 |
8 | Deleting an Enlistment from a Project does not delete a Code Location, nor will it interrupt Open Hub download activity against that Code Location. The Code Location and all of its source code and metrics remain in the Open Hub database; only the Enlistment link is modified.
9 |
10 | ### Properties
11 |
12 | + __id__
13 | The unique ID of the Code Location.
14 | + __type__
15 | The source control type. Supported values are:
16 | - _SvnRepository_
17 | Subversion
18 | - _CvsRepository_
19 | CVS
20 | - _GitRepository_
21 | Git
22 | - _HgRepository_
23 | Mercurial
24 | - _BzrRepository_
25 | Bazaar
26 |
27 | + __url__
28 | The public URL for the source control server.
29 | + __module_name__
30 | For CVS repositories only, this is the module name. For Git repositories only, this is the branch name. For all other repository types, this element is omitted.
31 | + __username__
32 | An optional username, if one is required to access the source control server.
33 | + __password__
34 | An optional password, if one is required to access the source control server.
35 | + __logged_at__
36 | The last time the Open Hub servers successfully queried the source control server for changes.
37 | + __commits__
38 | The number of commits which the Open Hub servers have successfully downloaded from the source control server.
39 | + __ohloh_job_status__
40 | If the most recent attempt by Open Hub to query the source control server for changes failed or was interrupted, this value will be `failed`. In all other cases it is `success`.
41 |
42 | ### URL
43 | Code Locations cannot be directly queried at this time. Access them by using the [Enlistments](enlistment.md) methods.
44 |
--------------------------------------------------------------------------------
/reference/contributor_fact.md:
--------------------------------------------------------------------------------
1 | ## ContributorFact
2 |
3 | A ContributorFact contains a selection of high-level statistics about a person who commited source code to a [Project](/reference/project.md). One ContributorFact record exists for each contributor.
4 |
5 | A ContributorFact is part of an [Analysis](/reference/analysis.md), and is derived from lower-level statistics contained within the Analysis.
6 |
7 | A new ContributorFact is created for each Project contributor whenever a new Analysis is created for the Project.
8 |
9 | ContributorFacts only exist after Open Hub has downloaded and analyzed the project source code.
10 |
11 | ### Properties
12 |
13 |
14 | + __analysis_id__
15 | The unique ID for the [Analysis](/reference/analysis.md) which provided the source data for this ContributorFact.
16 | + __contributor_id__
17 | The ID for the person who contributed the code measured in this ContributorFact. The `contributor_id` is not globally unique. It is derived from the author name found in the source control server log, and is unique within the scope of an individual project only.
18 | + __contributor_name__
19 | The name used by the author of this code when committing to the source control server.
20 | + __account_id__
21 | If this contribution has been claimed by an Open Hub member, the element contains the unique ID of the Open Hub [Account](/reference/account.md). Otherwise, this element is omitted.
22 | + __account_name__
23 | If this contribution has been claimed by an Open Hub member, this element contains the Account name. Otherwise, this element is omitted.
24 | + __primary_language_id__
25 | The unique ID of the [Language](/reference/language.md) most often used by this contributor, measured by the number of code lines added. If this contributor has not committed any code in a language which Open Hub can recognize, this value will be null.
26 | + __primary_language_nice_name__
27 | The `nice_name` of the Language specified by `primary_language_id`.
28 | + __comment_ratio__
29 | The fraction of new lines added by this contributor which are comments. Note that Open Hub does not track the net lines of current code attributable to an specific individual. This statistic merely sums over all new lines added, and does not consider whether the added lines were later removed by this contributor or any other.
30 | + __first_commit_time__
31 | The time of the first commit by this contributor.
32 | + __last_commit_time__
33 | The time of the last commit by this contributor.
34 | + __man_months__
35 | The total number of calendar months in which this contributor made at least one commit. Note that this is not simply the number of months between `first_commit_time` and `last_commit_time`: months in which there was no activity for this contributor are not counted.
36 | + __commits__
37 | The total number of commits made by this contributor.
38 | + __contributor_language_facts__
39 | A collection of [ContributorLanguageFacts](/reference/contributor_language_fact.md) may be included here, covering statistics in individual [Languages](/reference/language.md). This collection is only present when ContributorFacts are queried individually.
40 |
41 | ### URL
42 | To get a single ContributorFact based on the latest Analysis for a Project:
43 | ```shell
44 | curl https://www.openhub.net/p/{project_id}/contributors/{contributor_id}.xml
45 | ```
46 | This ContributorFact will include within it a collection of [ContributorLanguageFacts](/reference/contributor_language_fact.md) covering statistics for individual languages.
47 |
48 | ### Collection URL
49 | To get a list of all ContributorFacts based on the lastest Analysis for a Project:
50 | ```shell
51 | curl https://www.openhub.net/p/{project_id}/contributors.xml
52 | ```
53 | ContributorFacts returned from this call will not include ContributorLanguageFacts. Those can be obtained by retrieving ContributorFacts individually only.
54 |
55 | The project collection request supports the standard [collection request parameters](/README.md#collection-requests), with the following details:
56 |
57 | + __query__
58 | If supplied, only ContributorFacts with a matching `contributor_name` will be returned. Open Hub account names are not matched.
59 | + __sort__
60 | ContributorFact collections support the following sort options:
61 | - __name__
62 | - __kudo_position__
63 | - __commits__
64 | Highest commits, first
65 | - __commits_12_mo (default)__
66 | Highest commits in past twelve months, first
67 | - __language__
68 | - __latest_commit__
69 | - __newest__
70 | - __oldest__
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/reference/contributor_language_fact.md:
--------------------------------------------------------------------------------
1 | ## ContributorLanguageFact
2 |
3 | A ContributorLanguageFact contains a selection of [Language](/reference/language.md)-specific statistics about a single person who commited source code to a [Project](/reference/project.md).
4 |
5 | One ContributorFact record exists for each Language used by a contributor.
6 |
7 | The ContributorLanguageFact is very similar to a [ContributorFact](/reference/contributor_fact.md). The difference is that a ContributorLanguageFact contains statistics for a particular Language only, while a ContributorFact contains summary statistics across all languages used by the contributor.
8 |
9 | A ContributorLanguageFact is part of an Analysis, and is derived from lower-level statistics contained within the [Analysis](/reference/analysis.md). New ContributorLanguageFacts are created for each Project contributor whenever a new Analysis is created for the Project.
10 |
11 | ContributorLanguageFacts only exist after Open Hub has downloaded and analyzed the project source code.
12 |
13 | ### Properties
14 |
15 | + __analysis_id__
16 | The unique ID for the [Analysis](/reference/analysis.md) which provided the source data for this ContributorFact.
17 | + __contributor_id__
18 | The ID for the person who contributed the code measured in this ContributorLanguageFact. The `contributor_id` is not globally unique. It is derived from the author name found in the source control server log, and is unique within the scope of an individual project only.
19 | + __contributor_name__
20 | The name used by the author of this code when committing to the source control server.
21 | + __language_id__
22 | The unique ID of the [Language](/reference/language.md) measured.
23 | + __language_nice_name__
24 | The `nice_name` of the Language measured.
25 | + __comment_ratio__
26 | The fraction of new lines added by this contributor in this language which are comments. Note that Open Hub does not track the net lines of current code attributable to an specific individual. This statistic merely sums over all new lines added, and does not consider whether the added lines were later removed by this contributor or any other.
27 | + __man_months__
28 | The total number of calendar months in which this contributor made at least one commit using this Language. Months in which there was no activity in this Language for this contributor are not counted.
29 | + __commits__
30 | The total number of commits made in this Language by this contributor.
31 |
32 | ### Collection URL
33 | To get a list of all ContributorLanguageFacts for a particular contributor, based on the lastest Analysis for a Project:
34 | ```shell
35 | curl https://www.openhub.net/p/{project_id}/contributors/{contributor_id}.xml
36 | ```
37 | This is the same URL used to obtain a [ContributorFact](/reference/contributor_fact.md). The ContributorFact returned by this call will include within it a collection of ContributorLanguageFacts.
38 |
--------------------------------------------------------------------------------
/reference/enlistment.md:
--------------------------------------------------------------------------------
1 | ## Enlistment
2 | An Enlistment joins a [Project](/reference/project.md) to a source control [Code Location](/reference/code_location.md).
3 |
4 | Once added to the Open Hub database, a Code Location is permanent. However, Enlistments to that Code Location may be added or removed at any time. Many Projects may share a single CodeLocation.
5 |
6 | ### Properties
7 |
8 | + __id__
9 | The unique ID of the Enlistment.
10 | + __project_id__
11 | The unique ID of the [Project](/reference/project.md).
12 | + __code_location__
13 | The [Code Location](/reference/code_location.md) record will be included in full here.
14 |
15 | ### URL
16 | To get a single Enlistment
17 | ```shell
18 | curl GET https://www.openhub.net/p/{project_id}/enlistments/{enlistment_id}.xml
19 | ```
20 |
21 | ### Collection URL
22 | To get a list of all enlistments for a particular project:
23 | ``` shell
24 | curl https://www.openhub.net/p/{project_id}/enlistments.xml
25 | ```
26 |
27 | The Enlistment collection method supports the standard [collection request parameters](/README.md#collection-requests) with the following details:
28 |
29 | + __query__
30 | If supplied, enlistments with a code_location URL matching the query string will be returned.
31 | + __sort__
32 | Enlistment collections support the following sort options:
33 | - __module_name__
34 | - __project__
35 | - __type__
36 | - __url (default)__
37 |
38 |
39 |
--------------------------------------------------------------------------------
/reference/factoid.md:
--------------------------------------------------------------------------------
1 | ## Factoid
2 |
3 | A Factoid is a short, high-level bullet point delivering a simple observation about a [Project](/reference/project.md). Factoids are derived from an Analysis, and new Factoids are created for a Project every time a new [Analysis](/reference/analysis.md) is created.
4 |
5 | On the Open Hub web site, Factoids are rendered in the Nutshell section of the project summary page. Factoids also are available in several of the sharing widgets available for embedding on websites.
6 |
7 | A Project has factoids only if Open Hub has downloaded and analyzed its source code.
8 |
9 | ### Properties
10 | + __id__
11 | The unique ID for the Factoid. Factoid IDs change every time the Project is reanalyzed, so it’s unwise to store these IDs for long periods.
12 |
13 | + __analysis_id__
14 | The unique ID of the [analysis](/reference/analysis.md) used to calculate this factoid.
15 |
16 | + __type__
17 | The Factoid type. The possible types are defined below.
18 |
19 | + __description__
20 | A short, human-readable description. This is the bullet point text which appears on the Open Hub project page.
21 |
22 | + __severity__
23 | An integer from -3 to +3 which rates the relative severity of the factoid. Negative numbers generally indicate bad news, positive numbers generally indicate good news. Open Hub uses these numbers to select icons to display beside the factoids. All factoids of the same type have the save severity.
24 |
25 | ### Collection URL
26 | To get a list of all current Factoids for a particular Project:
27 | ```shell
28 | curl https://www.openhub.net/p/{project_id}/factoids.xml
29 | ```
30 | The collection request does not support any filtering, sorting or paging. You will always receive the entire collection of factoids, ordered by descending priority.
31 |
32 | ### Factoid Types
33 |
34 | + __FactoidActivityDecreasing__
35 | During the last twelve calendar months, there were at least 25% fewer commits to this project than in the prior twelve calendar months.
36 |
37 | + __FactoidActivityStable__
38 | During the last twelve calendar months, the commit count was within +/- 25% of the count for the prior twelve calendar months.
39 |
40 | + __FactoidActivityIncreasing__
41 | During the last twelve calendar months, there were at least 25% more commits to this project than in the prior twelve calendar months.
42 |
43 | + __FactoidAgeYoung__
44 | The source control repository is less than 1 year old.
45 |
46 | + __FactoidAgeEstablished__
47 | The source control repository is 1 to 3 years old.
48 |
49 | + __FactoidAgeOld__
50 | The source control repository is 3 to 5 years old.
51 |
52 | + __FactoidAgeVeryOld__
53 | The source control repository is 5 years old or older.
54 |
55 | + __FactoidCommentsVeryLow__
56 | Compared to all other projects written in the same language, the comment ratio for this project is in the bottom 10%.
57 |
58 | + __FactoidCommentsLow__
59 | Compared to all other projects written in the same language, the comment ratio for this project is in the bottom 33% but not in the bottom 10%.
60 |
61 | + __FactoidCommentsAverage__
62 | Compared to all other projects written in the same language, the comment ratio for this project is in the middle 33%.
63 |
64 | + __FactoidCommentsHigh__
65 | Compared to all other projects written in the same language, the comment ratio for this project is in the top 33% but not in the top 10%.
66 |
67 | + __FactoidCommentsVeryHigh__
68 | Compared to all other projects written in the same language, the comment ratio for this project is in the top 10%.
69 |
70 | + __FactoidTeamSizeZero__
71 | No commits were made to this project in the last 12 months.
72 |
73 | + __FactoidTeamSizeOne__
74 | Only a single contributor made commits to this project in the last 12 months.
75 |
76 | + __FactoidTeamSizeSmall__
77 | Two or three contributors made commits to this project in the last 12 months.
78 |
79 | + __FactoidTeamSizeAverage__
80 | 4 to 6 contributors made commits to this project in the last 12 months.
81 |
82 | + __FactoidTeamSizeLarge__
83 | 7 to 27 contributors made commits to this project in the last 12 months.
84 |
85 | + __FactoidTeamSizeVeryLarge__
86 | 28 or more contributors made commits to this project in the last 12 months.
87 |
88 | __Note about "mostly written in"__ - "... is mostly written in" bullet point listed in the Nutshell section of project summaries and in widgets displaying factoid information is not technically a factoid. This element is actually the `main_language_name` property on an [analysis](/reference/analysis.md).
89 |
--------------------------------------------------------------------------------
/reference/kudo.md:
--------------------------------------------------------------------------------
1 | ## Kudo
2 | A Kudo is a simple gesture of thanks, praise, or endorsement from an Open Hub [account](/reference/account.md) to another person. An account may send Kudos to as many people as desired.
3 |
4 | Kudos can be sent directly to another Open Hub account, or they may be sent to a contributor on a Project who does not have an Open Hub account. This flexibility makes Kudo records slightly complex.
5 |
6 | When a Kudo is sent directly to an Open Hub Account, the recipient is identified by `receiver_account_id`.
7 |
8 | When a Kudo is sent to a contributor on a Project who does not have an Account, the Kudo record contains both `contributor_id` and `project_id`, which together uniquely identify the recipient.
9 |
10 | Ocassionally, an Open Hub Account holder may claim to be a Project contributor who has some existing Kudos. When this happens, the existing Kudos become linked to the Account, and the Kudos will now have all three properties: `receiver_account_id`, `contributor_id`, and `project_id`.
11 |
12 | ### Properties
13 | + __created_at__
14 | The time at which this Kudo was sent.
15 | + __sender_account_id__
16 | The unique ID of the [Account](account.md) sending this Kudo.
17 | + __sender_account_name__
18 | The name of the [Account](account.md) sending this Kudo.
19 | + __receiver_account_id__
20 | If this Kudo can be linked to an Account, this is the unique ID of the Account receiving this Kudo. Otherwise, this element is omitted.
21 | + __receiver_account_name__
22 | If this kudo can be linked to an Account, this is the name of the Account receiving this Kudo. Otherwise, this element is omitted.
23 | + __project_id__
24 | If this Kudo was sent to a Project contributor instead of an Account, this is the unique ID of the [Project](project.md). Otherwise, this element is omitted.
25 | + __project_name__
26 | If this Kudo was sent to a Project contributor instead of an Account, this is the Project name. Otherwise, this element is omitted.
27 | + __contributor_id__
28 | If this Kudo was sent to a Project contributor instead of an Account, this is the unique ID of the contributor. Otherwise, this element is omitted.
29 | + __contributor_name__
30 | If this Kudo was sent to a Project contributor instead of an account, this is the name which appears in the source control logs. Otherwise, this element is omitted.
31 |
32 | ### Collection URL
33 | To get a list of all Kudos received by an Account:
34 | ```shell
35 | curl https://www.openhub.net/accounts/{account_id}/kudos.xml
36 | ```
37 | To get a list of all Kudos sent by an Account:
38 | ```shell
39 | curl https://www.openhub.net/accounts/{account_id}/kudos/sent.xml
40 | ```
41 | These methods do not support any sorting, filtering, or paging options. You will always receive the complete list of all Kudos, sorted from new to old.
42 |
43 | If you do not know the Account ID, you can also query for Kudos using the MD5 hash of the email address. Read more about email-based queries [here](/email_lookup.md).
44 |
45 |
--------------------------------------------------------------------------------
/reference/kudo_score.md:
--------------------------------------------------------------------------------
1 | ## Kudo Score
2 |
3 | Every night, a KudoScore is generated for every Open Hub Account and Project contributor (collectively called ‘participants’ here). These scores are derived from the [Kudos](kudo.md) sent between participants. You can read a general outline of the KudoRank algorithm [here](http://blog.openhub.net/kudos/).
4 |
5 | Not everyone has a KudoScore. Because KudoScores are calculated only once per day, new Accounts and contributors may not have a kudo score. On the Open Hub web site, unscored Accounts and contributors are displayed with a default KudoRank of 1.
6 |
7 | ### Properties
8 |
9 | + __kudo_rank__
10 | The KudoRank, which is an integer from 1 to 10. Higher ranks are better. KudoRanks are assigned on a curve, with a certain fraction of people receiving each KudoRank.
11 | + __position__
12 | An integer which orders all participants. The person with `position` equals 1 is the highest-ranked person on Open Hub.
13 |
14 | ### URL
15 | KudoScores cannot be queried directly. They are always returned within an [Account](account.md) record.
16 |
--------------------------------------------------------------------------------
/reference/language.md:
--------------------------------------------------------------------------------
1 | ## Language
2 |
3 | A Language record contains the name and various statistics related to a programming language.
4 |
5 | Language statistics are updated daily.
6 |
7 | ### Properties
8 |
9 | + __id__
10 | The unique ID of the language.
11 | + __name__
12 | A short, unique name for the language. Primarily for internal Open Hub use.
13 | + __nice_name__
14 | A human-friendly name for the language.
15 | + __category__
16 | Either code, markup, or build, which indicates that the language is either a “standard” programming language, a document markup language such as XML, or a build script such as a makefile.
17 | + __code__
18 | The total net lines of code, excluding comments and blank lines, written in this language across all projects on Open Hub.
19 | + __comments__
20 | The total net comment lines written in this language across all projects on Open Hub.
21 | + __blanks__
22 | The total net blank lines in this language across all projects on Open Hub.
23 | + __comment_ratio__
24 | A precomputed floating-point value for the percent of lines in this language that are comments, across all projects on Open Hub.
25 | + __projects__
26 | The total number of Projects on Open Hub which currently include at least one line in this language.
27 | + __contributors__
28 | The total number of contributors on Open Hub who have written at least one line of code in this language that still exists today.
29 | + __commits__
30 | The total number of commits on Open Hub which include at least one line in this language.
31 |
32 | ### Collection URL
33 | To get a paginated list of all Languages:
34 | ```shell
35 | curl https://www.openhub.net/languages.xml
36 | ```
37 | The Language collection request supports the standard [collection request parameters](/README.md#collection-requests), with the following sort options:
38 |
39 | + __total__
40 | Results are sort by the total source lines, including comments and blanks, from highest to lowest.
41 | + __code__
42 | Results are sorted by code lines only from highest to lowest.
43 | + __projects__
44 | Results are sorted by the number of projects, from highest to lowest.
45 | + __comment_ratio__
46 | Results are sorted by comment_ratio from highest to lowest.
47 | Results are sorted by the number of Projects, from highest to lowest.
48 | + __contributors__
49 | Results are sorted by the number of contributors, from highest to lowest
50 | + __commits__
51 | Results are sorted by the number of commits, from highest to lowest.
52 | + __name (default)__
53 | Results are sorted alphabetically by nice_name.
54 |
--------------------------------------------------------------------------------
/reference/organization-collection.md:
--------------------------------------------------------------------------------
1 | ##Organization
2 | An organization is an entity which contains a collection of projects and accounts.
3 |
4 |
5 | ### Properties
6 | + __name__ Organization Name
7 | + __url__ XML Api URL for the current organization.
8 | + __html_url__ The URL for the current organization page on Open Hub.
9 | + __created_at__ The time at which the organization was initially added to Open Hub.
10 | + __updated_at__ The time of most recent modification to the organization record.
11 | + __description__ The optional description of the current organization, currently limited to 800 characters.
12 | + __homepage_url__ An optional URL for the home page of the organization, e.g Apache Software Foundation (www.apache.org)
13 | + __url_name__ A short, unique, handle for the current organization. e.g for url_name as 'apache' the equivalent web link is www.openhub.net/orgs/apache
14 | + __small_logo_url__ An url to the organization’s 32×32 pixels logo image.
15 | + __medium_logo_url__ An url to the organization’s 64×64 pixels logo image.
16 | + __type__ The type of the organizations(Non-profit/commercial/Government/Educational).
17 | + __projects_count__ The number of portfolio projects under the organization.
18 | + __affiliated_committers__ The count of number of committers affiliated to the organization.
19 |
20 |
21 | ### Collection URL
22 | ```shell
23 | https://www.openhub.net/orgs.xml?api_key={api_key}&page={number}&sort={projects}&query={keyword}
24 | ```
25 |
26 | The organization collection request supports the standard [collection request parameters](/README.md#collection-requests), with the following details:
27 |
28 | + __query__ If supplied, only organizations matching the query string will be returned.
29 |
30 | - An organization match occurs if its name, description, or any of its tags contain the query string.
31 |
32 | + __sort__ Organization collection supports the following sort options :
33 |
34 | - __name__ Sort by organization name.
35 | - __projects_count__ Sort by number of portfolio projects in the organization.
36 | - __created_at__ Sort by the organization created date/time.
37 | - __updated_at__ Sort by organization record's last updated date/time.
38 |
39 | + __page__ Results page for the organization collection xml api.
40 |
41 | - The first page of results are displayed when the API is queried without passing a 'page' parameter in the url.
42 | - Successive pages of results can be queried using ```page=1``` upto ```page=n```
43 |
44 | #### Example
45 |
46 | ```ruby
47 | https://www.openhub.net/orgs.xml?api_key=some_example_api_key&page=2&sort=projects_count&query=java
48 | ```
49 |
--------------------------------------------------------------------------------
/reference/organization.md:
--------------------------------------------------------------------------------
1 | ### Organization
2 | An organization is an entity which contains a collection of projects and accounts.
3 |
4 |
5 | ### Properties
6 | + __name__ Organization Name
7 | + __url__ XML API URL for the organization.
8 | + __html_url__ The URL for the organization page on Open Hub.
9 | + __created_at__ The time at which the organization was initially added to Open Hub.
10 | + __updated_at__ The time of most recent modification to the organization record.
11 | + __description__ The optional description of the organization, currently limited to 800 characters.
12 | + __homepage_url__ An optional URL for the home page of the organization, e.g Apache Software Foundation (www.apache.org)
13 | + __url_name__ A short, unique, handle for the organization. e.g for url_name as 'apache' the equivalent web link is www.openhub.net/orgs/apache
14 | + __small_logo_url__ An url to the organization’s 32×32 pixels logo image.
15 | + __medium_logo_url__ An url to the organization’s 64×64 pixels logo image.
16 | + __type__ The type of the organization(Non-profit/Commercial/Government/Educational).
17 | + __inforgraphic_details__ Details presented in the organization page inforgraphic image
18 | + __outside_committers__
19 | + __outside_committers_commits__
20 | + __projects_having_outside_commits__
21 | + __portfolio_projects__
22 | + __affiliators__
23 | + __affiliators_committing_to_portfolio_projects__
24 | + __affiliator_commits_to_portfolio_projects__
25 | + __affiliators_commiting_projects__
26 | + __outside_projects__
27 | + __outside_projects_commits__
28 | + __affiliators_committing_to_outside_projects__
29 | + __portfolio_projects__ First 10 Portfolio Projects for the requested organization
30 | + __project__ Each project in the list with the following details
31 | + __name__
32 | + __activity__
33 | + __primary_language__
34 | + __i_use_this__
35 | + __community_rating__
36 | + __twelve_mo_activity_and_year_on_year_change__
37 | + __commits__
38 | + __change_in_commits__
39 | + __percentage_change_in_commits__
40 | + __contributors__
41 | + __change_in_contributors__
42 | + __percentage_change_in_committers__
43 | + __detailed_page_url__ Url for paginated listing of all portfolio projects
44 | + __outside_projects__ First 10 Outside Projects for the requested organization.
45 | + __project__ Each project in the list with the following details
46 | + __name__
47 | + __activity__
48 | + __claimed_by__
49 | + __i_use_this__
50 | + __community_rating__
51 | + __affiliates_contributing__
52 | + __commits_by_current_affiliates__
53 | + __detailed_page_url__ Url for paginated listing of all outside projects
54 | + __outside_committers__ First 10 Outside Committers for the requested organization
55 | + __contributor__ Each account in the list with the following details
56 | + __name__
57 | + __kudos__
58 | + __level__
59 | + __affiliated_with__
60 | + __contributions_to_portfolio_projects__
61 | + __projects__
62 | + __twelve_mo_commits__
63 | + __detailed_page_url__ Url for paginated listing of all outside committers
64 | + __affiliated_committers__ First 10 Affiliated Committers for the requested organization
65 | + __affiliator__ Each account in the list with the following details
66 | + __name__
67 | + __kudos__
68 | + __level__
69 | + __most_commits__
70 | + __project__
71 | + __commits__
72 | + __most_recent_commit__
73 | + __project__
74 | + __date__
75 | + __detailed_page_url__ Url for paginated listing of all affiliated committers
76 |
77 |
78 | ### URL
79 | ```shell
80 | https://www.openhub.net/orgs/{org_url_name}.xml?api_key={api_key}&view={view_option}
81 | ```
82 |
83 | view_option will return the requested organization related data-table(maximum of 10 records)
84 |
85 | - The view option can be one of the following four ````portfolio_projects````, ````outside_projects````, ````affiliated_committers```` or ````outside_committers````
86 |
87 | #### Examples
88 |
89 | ```ruby
90 | https://www.openhub.net/orgs/mozilla.xml?api_key=some_example_api_key&view=portfolio_projects
91 | ```
92 |
93 | ```ruby
94 | https://www.openhub.net/orgs/mozilla.xml?api_key=some_example_api_key&view=outside_projects
95 | ```
96 |
97 | ```ruby
98 | https://www.openhub.net/orgs/mozilla.xml?api_key=some_example_api_key&view=affiliated_committers
99 | ```
100 |
101 | ```ruby
102 | https://www.openhub.net/orgs/mozilla.xml?api_key=some_example_api_key&view=outside_committers
103 | ```
104 |
--------------------------------------------------------------------------------
/reference/outside_committers.md:
--------------------------------------------------------------------------------
1 | ##Outside Committers
2 | People that are not part of an organization but commit to its projects
3 |
4 |
5 | ### Properties
6 |
7 | + __contributor__
8 | + __name__ Name of the user account
9 | + __kudos__ Kudos obtained by the user account
10 | + __level__ Level of the user account
11 | + __affiliated_with__ Organization to which the user is affiliated to
12 | + __contributions_to_portfolio_projects__
13 | + __projects__ Names of the portfolio projects to which the contributor commits to
14 | + __twelve_mo_commits__ Commits made by the contributor to portfolio projects in the last 12 months
15 | + __detailed_page_url__ This page's relative url
16 |
17 |
18 | ### URL
19 |
20 | ```shell
21 | https://www.openhub.net/orgs/{org_name}/outside_committers.xml?api_key={api_key}&page={number}
22 | ```
23 |
24 | #### Example
25 |
26 | ```ruby
27 | https://www.openhub.net/orgs/mozilla/outside_committers.xml?api_key=some_example_api_key&page=2
28 | ```
29 |
--------------------------------------------------------------------------------
/reference/outside_projects.md:
--------------------------------------------------------------------------------
1 | ##Outside Projects
2 | Projects that are not part of an organization but are commtted to by its members
3 |
4 |
5 | ### Properties
6 |
7 | + __project__
8 | + __name__ Name of the project
9 | + __activity__ Project's activity level like low, high etc..
10 | + __primary_language__ The primary language in which the projects repos have code in
11 | + __i_use_this__ Number of people who mark that they use this
12 | + __community_rating__ Average rating of the project as rated by openhub users
13 | + __affiliates_contributing__ No of people that belong to the organization that commit to outside projects
14 | + __commits_by_current_affiliates__ No of commits made by the organization people to outside projects
15 | + __detailed_page_url__ This page's relative url
16 |
17 |
18 | ### URL
19 |
20 | ```shell
21 | https://www.openhub.net/orgs/{org_name}/outside_projects.xml?api_key={api_key}&page={number}
22 | ```
23 |
24 | #### Example
25 |
26 | ```ruby
27 | https://www.openhub.net/orgs/mozilla/outside_projects.xml?api_key=some_example_api_key&page=2
28 | ```
29 |
--------------------------------------------------------------------------------
/reference/portfolio_projects.md:
--------------------------------------------------------------------------------
1 | ##Portfolio Projects
2 | Projects that belong to a specific organization
3 |
4 |
5 | ### Properties
6 |
7 | + __project__
8 | + __name__ Name of the project
9 | + __activity__ Project's activity level like low, high etc..
10 | + __primary_language__ The primary language in which the projects repos have code in
11 | + __i_use_this__ Number of people who mark that they use this
12 | + __community_rating__ Average rating of the project as rated by openhub users
13 | + __twelve_mo_activity_and_year_on_year_change__ Last 12 months activity compared with previous 12 months activity
14 | + __commits__ No of commits in the last 12 months
15 | + __change_in_commits__ Diff between no of commits in this 12 months and the previous 12 months before that
16 | + __percentage_change_in_commits__ % measure of change in commits
17 | + __contributors__ No of contributors in the last 12 months
18 | + __change_in_contributors__ Diff between no of committers in this 12 months and the previous 12 months before that
19 | + __percentage_change_in_committers__ % measure of change in contributors
20 | + __detailed_page_url__ This page's relative url
21 |
22 |
23 | ### URL
24 |
25 | ```shell
26 | https://www.openhub.net/orgs/{org_name}/projects.xml?api_key={api_key}&page={number}
27 | ```
28 |
29 | #### Example
30 |
31 | ```ruby
32 | https://www.openhub.net/orgs/mozilla/projects.xml?api_key=some_example_api_key&page=2
33 | ```
--------------------------------------------------------------------------------
/reference/position.md:
--------------------------------------------------------------------------------
1 | ## Position
2 | A position represents a contribution or series of contributions that an account holder has made to a project within Open Hub. It corresponds to a committer ID for a source code repository for a particular project.
3 |
4 | ### Properties
5 |
6 | + __title__
7 | An optional field that contains the title for this position. Example: “Lead Developer”. This field is filled in by the account holder.
8 | + __organization__
9 | An optional field that contains the organization name for this position. This field will be filled in if the account holder has designated that this position’s contributions were made on behalf of an organization. Example: “IBM Corporation”.
10 | + __html_url__
11 | The url to the contributor page on Open Hub.
12 | + __created_at__
13 | The time at which this Position was originally created on Open Hub.
14 | + __started_at__
15 | Optional field that contains the time at which this position was started. This field may be filled in by the account holder if this position is not backed by commits (e.g. the user contributed documentation to the projects wiki or authored and submitted a patch committed by a project maintainer).
16 | + __ended_at__
17 | Option field that contains the time at which this position was ended. This field may be filled in by the account holder if the position is not backed by commits.
18 | + __sparkline_url__
19 | The url to the sparkline that represents the account holder’s commit activity for the current position.
20 | + __commits__
21 | The total number of commits made by the account holder at this position.
22 | + __project__
23 | The Project that this position is attached to. This node will contain all of the properties for the specific [project](project.md).
24 |
25 | ### URL
26 | To get positions for an account:
27 | ```shell
28 | curl https://www.openhub.net/accounts/{account_id}/positions.xml
29 | ```
30 |
--------------------------------------------------------------------------------
/reference/project.md:
--------------------------------------------------------------------------------
1 | ## ProjectH
2 | A Project represents a collection of source code, documentation, and web sites treated together as a unit. It’s what most people might call an ‘application’ or ‘library’.
3 |
4 | ### Properties
5 | + __id__
6 | The unique ID for the Project.
7 | + __name__
8 | The project name. Currently limited to 40 characters, and must be unique on Open Hub.
9 | + __created_at__
10 | The time at which this Project was initially added to the Open Hub database.
11 | + __updated_at__
12 | The time of the most recent modification of this Project record.
13 | + __description__
14 | An optional description. Currently limited to 800 characters.
15 | + __homepage_url__
16 | An optional URL to the project home page.
17 | + __download_url__
18 | An optional URL to a website hosting project downloads.
19 | + __vanity_name__
20 | A short, unique name for this project. This name is used in Open Hub project URLs.
21 | + __medium_logo_url__
22 | An url to the project’s 64×64 pixels logo image.
23 | + __small_logo_url__
24 | An url to the project’s 32×32 pixels logo image.
25 | + __user_count__
26 | The number of users currently using this project.
27 | + __average_rating__
28 | A floating point value from 1.0 to 5.0, representing the average value of all user ratings. 1.0 is the worst possible rating and 5.0 is the highest possible rating. Will be null if no users have rated this project.
29 | + __rating_count__
30 | The number of users who have rated this project.
31 | + __review_count__
32 | The number of users who have reviewed this project.
33 | + __analysis_id__
34 | The unique ID of the current best [Analysis](analysis.md) for this project. If the project has never been analyzed, this element will be empty.
35 | + __analysis__
36 | For convenience, the current best Analysis for the project is included in this element. This object is present only when you have requested a single project — if the project was returned as part of a collection, the analysis object will not be present.
37 | + __url__
38 | The xml api url for the current Project.
39 | + __html_url__
40 | The url to the current Projects details page on Open Hub.
41 | + __factoids__
42 | The factoids for the current analysis of the project will be included under this node.
43 |
44 | ```xml
45 |
46 | Very large, active development team
47 | Mature, well-established codebase
48 | Increasing year-over-year development activity
49 | Few source code comments
50 |
51 | ```
52 |
53 | + __tags__
54 | The tags for the current project will be included under this node.
55 |
56 | ```xml
57 |
58 | ruby
59 | gem
60 | web
61 |
62 | ```
63 |
64 | + __language__
65 | The language breakdown chart for the current Analysis will be included under this node. The node will have the following children:
66 | - __@graph_url__
67 | This is the url to the PNG image that depicts the language breakdown for the current Analysis. The colors referenced in each languages @color attribute will be used in this image.
68 | - __language__
69 | Not every language will have a entry. Open Hub will combine languages that do not make up a significant percentage into a aggregate entry “N Other”. This entry can be identified by either its @color, always “000000″ or @id, always “”.
70 | Each language will contain the following data
71 | - @color The color code that Open Hub uses to represent this language on the website. This color is also used in the language breakdown graph image.
72 | - @percentage The percentage of lines of code that the current language represents in the current Analysis
73 | - @id The Open Hub language id.
74 |
75 | ```xml
76 |
77 | C++
78 | C
79 | JavaScript
80 | 28 Other
81 |
82 | ```
83 |
84 | + __similar_projects__
85 | The similar projects with regards to the tags will be included under this node.
86 | - __id__
87 | The unique ID for the Project.
88 | - __name__
89 | Full Name of the project
90 | - __vanity_url__
91 | A short, unique name for this project. This name is used in openhub project URLs.
92 |
93 | ```xml
94 |
95 |
96 | 1
97 | Ruby
98 | ruby
99 |
100 |
101 | ```
102 |
103 | + __licenses__
104 | The Licenses for the current project will be included under this node.
105 | - __name__
106 | Full Name of the License
107 | - __vanity_url__
108 | A human-friendly name of the License
109 |
110 | ```xml
111 |
112 |
113 | mit
114 | MIT License
115 |
116 |
117 | ```
118 |
119 | + __project_activity_index__
120 | The Project Activity Index (PAI) level
121 | - __value__
122 | The numerical value for the activity level. The values may be one of
123 | + 0 (NA)
124 | + 10 (New)
125 | + 20 (Inactive)
126 | + 30 (Very Low)
127 | + 40 (Low)
128 | + 50 (Moderate)
129 | + 60 (High)
130 | + 70 (Very High)
131 | - __description__
132 | The text description of the value as defined above
133 |
134 | ```xml
135 |
136 | 70
137 | Very High
138 |
139 | ```
140 |
141 | + __links__
142 | The links associated with the current project. Homepage and Download links are not included here.
143 | - __category__
144 | Link category on Open Hub
145 | - __title__
146 | - __url__
147 |
148 |
149 | ```xml
150 |
151 |
152 | Documentation
153 | http://www.luckytips.co.nr/firefox
154 | Tips n Tricks
155 |
156 |
157 | ```
158 |
159 | ### URL
160 | To get a single Project, including its current best Analysis:
161 | ```shell
162 | curl https://www.openhub.net/p/{project_id}.xml
163 | ```
164 |
165 | ### Collection URL
166 | To get a list of all Projects, not including their Analyses:
167 | ```shell
168 | curl https://www.openhub.net/p.xml
169 | ```
170 | The Project collection request supports the standard [collection request parameters](/README.md#collection-requests), with the following details:
171 |
172 | + __query__
173 | If supplied, only Projects matching the query string will be returned. A Project matches if its name, description, or any of its tags contain the query string.
174 | + __sort__
175 | Project collections support the following sort options:
176 |
177 | - __new__
178 | - __rating__
179 | - __active_committers__
180 | Highest active committers in past 12 months, first
181 | - __activity_level__
182 | - __stack_count__
183 | - __stack_count_reverse (default)__
184 | - __id__
185 | - __name__
186 | - __name_length__
187 | Length of project name. Shorter name, first
188 | - __updated_at__
189 | - __relevance__
190 |
191 |
192 |
193 |
--------------------------------------------------------------------------------
/reference/size_fact.md:
--------------------------------------------------------------------------------
1 | ## SizeFact
2 | A SizeFact is a pre-computed collection of statistics about [Project](project.md) source code. It provides monthly running totals of lines of code, commits, and developer effort.
3 |
4 | SizeFacts contain the running totals of [ActivityFacts](activity_fact.md).
5 |
6 | A SizeFact is derived from lower-level statistics contained in an [Analysis](analysis.md). SizeFacts are updated whenever a [Project](project.md) is re-analyzed.
7 |
8 | SizeFacts are availabled only after Open Hub has downloaded and analyzed the project source code.
9 |
10 | ### Properties
11 |
12 | + __month__
13 | Indicates the month covered by this SizeFact. Only the year and month fields are significant. This SizeFact record includes all development activity that occured during this month.
14 | + __code__
15 | The total net lines of code, excluding comments and blanks, as of the end of this month.
16 | + __comments__
17 | The total net lines of comments as of the end of this month.
18 | + __blanks__
19 | The total net blank lines as of the end of this month.
20 | + __comment_ratio__
21 | The fraction of net lines which are comments as of the end of this month.
22 | + __commits__
23 | The cumulative total number commits to the project source control, including this month.
24 | + __man_months__
25 | The cumulative total months of effort expended by all contributors on this project, including this month. For instance, if 1 contributor has worked for 3 months and 2 developers have each worked for 5 months, man_months will be 13. This is the running total of the [ActivityFact](activity_fact.md) `contributors` property.
26 |
27 | ### Collection URL
28 | To get all SizeFacts for a particular [Analysis](analysis.md):
29 | ```shell
30 | curl https://www.openhub.net/p/{project_id}/analyses/{analysis_id}/size_facts.xml
31 | ```
32 | If you do not know the ID of the current best Analysis for a Project, you can use the following shortcut:
33 | ```shell
34 | curl https://www.openhub.net/p/{project_id}/analyses/latest/size_facts.xml
35 | ```
36 |
37 | The call returns one SizeFact for each month, starting at the first month in which any code exists, and ending at the month in which Open Hub last created a new Analysis for this Project. Typically, the collection ends at the current month, but if the Project has not been re-analyzed in a while, the collection may end sooner.
38 |
39 | The results cannot be paginated or filtered. Results are sorted chronologically.
40 |
--------------------------------------------------------------------------------
/reference/stack.md:
--------------------------------------------------------------------------------
1 | ## Stack
2 |
3 | A Stack represents a collection of Projects used by a single person. A Stack belongs to an [Account](account.md)./,
4 |
5 | A Stack contains zero or more [StackEntries](stack_entry.md), each of which links the Stack to a single [Project](project.md).
6 |
7 | ### Properties
8 |
9 | + __id__
10 | The unique ID for the Stack.
11 | + __title__
12 | The name of the Stack.
13 | + __description__
14 | A short description about this Stack.
15 | + __updated_at__
16 | The most recent time at which any Projects were added to or removed from this Stack.
17 | + __project_count__
18 | The total number of Projects currently contained in this Stack.
19 | + __stack_entries__
20 | A collection of zero or more [StackEntries](stack_entry.md). If the Stack object was returned in response to a collection request (/projects/x/stacks.xml), you will receive only a single StackEntry corresponding to the Project in question.
21 | + __account_id__
22 | The unique ID of the [Account](account.md) which owns this Stack.
23 | + __account__
24 | For convenience, a full [Account](account.md) object may be included here.
25 |
26 | ### Collection URL
27 | To get a list of all Stacks for a particular Project:
28 | ```shell
29 | GET https://www.openhub.net/p/{project_id}/stacks.xml
30 | ```
31 | The Stacks returned in this collection will each contain only a single [StackEntry](stack_entry.md), corresponding to the Project in question.
32 |
33 | Each Stack in the result will also include an Account object.
34 |
35 | The Stack collection is paginated, and supports the standard [collection request parameters](/README.md#collection-requests) with the following details:
36 |
37 | + __query__
38 | If supplied, only Stacks owned by Accounts with names matching the query string will be returned.
39 | + __sort__
40 | Stack collections support the following sort options:
41 | - __id__
42 | - __name__ (default)
43 | - __created_at__ Time at which the Project was added to the stack
44 | - __project_count__
45 |
46 |
47 |
--------------------------------------------------------------------------------
/reference/stack_entry.md:
--------------------------------------------------------------------------------
1 | ## StackEntry
2 |
3 | A StackEntry joins a [Stack](stack.md) to a [Project](project.md).
4 |
5 | ### Properties
6 |
7 | + __id__
8 | The unique ID for the StackEntry.
9 | + __created_at__
10 | The time at which this Project was added to this Stack.
11 | + __stack_id__
12 | The unique ID of the Stack which contains this StackEntry.
13 | + __project_id__
14 | The unique ID of the Project.
15 | + __project__
16 | For convenience, a full Project object may be included here. If the Stack object was returned in response to an Account Stack request (/accounts/x/stacks/default.xml), the Project objects will be present.
17 |
18 | ### URL
19 | StackEntry object cannot be queried directly. They are included in a response to queries or [stacks](stack.md).
20 |
--------------------------------------------------------------------------------