The very early workings of an API ...

http://www.daniweb.com/api/documentation

Any ideas churning??

pritaeas commented: Top! +0
cereal commented: great! +0

Recommended Answers

All 284 Replies

A lot of reading functionability but no writing; Will there function to make our own client for posting threads/posts to Daniweb?

Nice though :)

This is something not seen on most forums.

This could prove very interesting as the API becomes more extensive :)

Edit: However I need to figure out how to call it from C# first :(

commented: I completely agree +0

A lot of reading functionability but no writing; Will there function to make our own client for posting threads/posts to Daniweb?

Not in the near future. Writing functionality would require the use of an API key for security purposes (trivial), which currently isn't implemented. However, the issue I have is that I think it will be a moderation nightmare to allow what could potentially be automated systems to post on behalf of members, even if it is throttled. I can certainly see the benefit of software that lets you post on your own terms (if you don't like the DaniWeb editor, for example), but right now it seems like a bit of a liability because there's no true way to regulate that a bot won't just be posting random gibberish every X minutes.

This could prove very interesting as the API becomes more extensive :)

I'm open to suggestions. It's pretty robust right now in the sense that you could actually recreate our member badges with your own design, just as an example. Check it out, play with it, and I'm open to feedback.

Edit: However I need to figure out how to call it from C# first :(

This should be trivial. The example provided uses PHP but that's neither here nor there. I don't know C# if it smacked me in the face, but a quick Google search revealed that the WebRequest class can be easily used to make POST requests. The API returns JSON, so then you'll need to use something to deserialize JSON and convert it to a C# object. I'm guessing that JSON is popular enough nowadays that this shouldn't be very involved either.

Will you update you RSS pull example to cUrl? Newbies trying will probably get an error since most hosts will not allow cross domain fopen wrappers (file_get_contents). It'll save you some questions IMO.

The ideas are flowing right now and I actually take back my statement that writing functionality is off the table. Perhaps for trusted usergroups?? The hurdle would be to mitigate the chance of abuse. If it's viable, it would definitely open up lots of possibilities for third-party software to recreate all of the basic functionality of the site.

Also, it should be noted, at this time you are only able to fetch the contents of the first post in an article. This is done to prevent scraping.

This is done to prevent scraping.

Anything in place to prevent flooding?

Not right now. (Gosh, should I say that in public?)

I was saving requests to the database in anticipation of flood protection, but then realized that that's two extra database queries per request, so I put the idea on freeze for now. I'm currently trying to figure out if I even need it ;) Requests get cached and they don't consume any more resources than any other page load, so I think even if a bot were to make repeated automated requests, we're not any more in jeopardy than we would be to a DoS attack.

This should be trivial. The example provided uses PHP but that's neither here nor there. I don't know C# if it smacked me in the face, but a quick Google search revealed that the WebRequest class can be easily used to make POST requests. The API returns JSON, so then you'll need to use something to deserialize JSON and convert it to a C# object. I'm guessing that JSON is popular enough nowadays that this shouldn't be very involved either.

Aye it most likely will be just something I've never done before so there is the slight learning curve!

Cheers shall have a look into that when out of the office as I still need to figure out navigation of our proxy servers :)

This news is a great step ahead I think. I'll take a look at this API when I reach home. In the meantime:

Not right now. (Gosh, should I say that in public?)

You can implement a rate-limiting feature similar to something used by Github I think. Each user (or some user group) can implement X API calls per day / per hour etc. Once that limit is reached, all further API calls return a denied HTTP status.

EDIT: Also, this opens up a distinct possiblity of a clean slate implementation of a true mobile compatible Daniweb.

commented: Good suggestion :) +0

Any ideas churning??

A DaniWeb API client challenge?

I'm writing this post for everyone who - like me - is trying to send requests with: Content-Type: application/json.

I figured it out the hard way (by capturing the packet sent from the PHP code sample) that the Content-Type needs to be multipart/form-data.

application/x-www-form-urlencoded (the content type when you do form submissions in browser) should also work out fine I think; the API is basically expecting POST data.

How long before you will start inserting advertising in the json returned from API?

Can a registered user request form data that will take into account user's account? For example if I want to pull only items to which I am subscribed? Is there a way to pass login details in the API call?

How long before you will start inserting advertising in the json returned from API?

LOL. You don't know it yet because you're a new member, but once you hit a threshold (of a dozen posts or so), you get to permanently disable ads on the site. I think that's pretty generous :)

Can a registered user request form data that will take into account user's account? For example if I want to pull only items to which I am subscribed? Is there a way to pass login details in the API call?

Not at this time, but this would definitely be on the todo list once API keys are implemented.

I'm just trying to get some initial opinions about the API and what direction you'd ultimately like to see it in. It's a big work in progress right now so everything is still up for changing.

It's not very useful then. It is basically the same as using rss feed, right?
There has to be a way to recognize the user, maybe by reading the same login cookie as the main website or using some type of authentication headers.

There will ultimately be a way to recognize the user in the near future. It simply hasn't been implemented yet.

It is already significantly more robust than the RSS feed. The RSS feeds simply pull the latest articles, optionally by forum or article type. Check out the API sample usage demos to see what you can do. As an exmaple, you can build member badges (http://www.daniweb.com/stats/get_badge) given the existing API functionality.

Member Avatar for diafol

This is quite nice Dani. Here's somethng I knocked up in about 20 minutes.

daniApi

I was thinking of creating a 'Top Trumps' type game, where you play a member's attibutes against another. You can tell I'm bored! Vacation and the kids are away :)

commented: Nice work Al +0
commented: Next stop collectible trading card game :) +0

Dramatic changes to the API coming soon. (In the interest of disclosure, parameter names will be changing, and we'll be moving to GET requests for read-only stuff and POST requests for writing). Yes, I said it ... we'll have write functionality.

commented: I like the enhancements, way better now ;) +0
Member Avatar for diafol

Dramatic changes to the API coming soon. (In the interest of disclosure, parameter names will be changing, and we'll be moving to GET requests for read-only stuff and POST requests for writing). Yes, I said it ... we'll have write functionality.

Phworr!

Member Avatar for LastMitch

@Dani

There will ultimately be a way to recognize the user in the near future. It simply hasn't been implemented yet.

How do you do that?

This thread is very interesting.

I never try this before but how does it work?

I notice it's PHP code but I don't have an USERID or ID:

http://www.daniweb.com/api/articles/{USERID}/{FORUMID}/{FILTER}/{ORDERBY}/{PAGE}

http://www.daniweb.com/api/posts/{TYPE}/{ID}/{FILTER}/{PAGE}

Is my ID in my profile? I don't see it.

How do I create that profile that diafol did? It looks neat!

Member Avatar for diafol

How do I create that profile that diafol did?

dw22

I used the original API documentation, but that's changed now, but it still seems to work. I assume that it will change further.

Here's the code - BUT - it was a quick fiddle - CSS all over the place (duplication) and class was an afterthought to the procedural crap I churned out. I used a local copy for the dw logo - so that'll be missing and also the font for the username is just a local font - so that'll be different. So spaghetti and all - here's the page, caveats given:

<style>
    td{
        font-family: Arial, Helvetica, sans-serif;
        padding: 3px 10px;  
        background-color: #65327B;
        text-align:right;
        border: 2px solid black;
        -webkit-border-radius: 10px;
        border-radius: 10px;
        color: white;
        font-weight: bold;
        font-size: 14px;
    }
    td + td{
        font-family: "Courier New", Courier, monospace;
        color: red; 
        background-color: white;
        text-align:center;
        border: 2px solid black;
        -webkit-border-radius: 10px;
        border-radius: 10px;
        width: 200px;
    }

    div.main{
        border: 5px solid #65327B;
        width: 340px;
        -webkit-border-radius: 10px;
        border-radius: 10px;
        margin: 30px;
        -moz-box-shadow: 10px 10px 5px #888;
-webkit-box-shadow: 10px 10px 5px #888;
box-shadow: 10px 10px 5px #888;
        background: #fcfff4; /* Old browsers */
background: -moz-linear-gradient(top,  #fcfff4 0%, #dfe5d7 40%, #b3bead 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fcfff4), color-stop(40%,#dfe5d7), color-stop(100%,#b3bead)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top,  #fcfff4 0%,#dfe5d7 40%,#b3bead 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top,  #fcfff4 0%,#dfe5d7 40%,#b3bead 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top,  #fcfff4 0%,#dfe5d7 40%,#b3bead 100%); /* IE10+ */
background: linear-gradient(to bottom,  #fcfff4 0%,#dfe5d7 40%,#b3bead 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfff4', endColorstr='#b3bead',GradientType=0 ); /* IE6-9 */

    }

    div.datarows{
        padding: 15px;  
    }

    div.topbit p{
        text-align: center; 
        margin:0;
    }

    div.topbit {
background: #65327b; /* Old browsers */
/* IE9 SVG, needs conditional override of 'filter' to 'none' */
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIxOSUiIHN0b3AtY29sb3I9IiM2NTMyN2IiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIzNyUiIHN0b3AtY29sb3I9IiNhODQ5YTMiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI0OSUiIHN0b3AtY29sb3I9IiNmM2ViZjQiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI2MyUiIHN0b3AtY29sb3I9IiNhODQ5YTMiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI4MiUiIHN0b3AtY29sb3I9IiM2NTMyN2IiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
background: -moz-linear-gradient(top,  #65327b 19%, #a849a3 37%, #f3ebf4 49%, #a849a3 63%, #65327b 82%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(19%,#65327b), color-stop(37%,#a849a3), color-stop(49%,#f3ebf4), color-stop(63%,#a849a3), color-stop(82%,#65327b)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top,  #65327b 19%,#a849a3 37%,#f3ebf4 49%,#a849a3 63%,#65327b 82%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top,  #65327b 19%,#a849a3 37%,#f3ebf4 49%,#a849a3 63%,#65327b 82%); /* Opera 11.10+ */
background: -ms-linear-gradient(top,  #65327b 19%,#a849a3 37%,#f3ebf4 49%,#a849a3 63%,#65327b 82%); /* IE10+ */
background: linear-gradient(to bottom,  #65327b 19%,#a849a3 37%,#f3ebf4 49%,#a849a3 63%,#65327b 82%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#65327b', endColorstr='#65327b',GradientType=0 ); /* IE6-8 */
    }
    p.big img{
        border: 2px solid white;    
    }
    p.dw{
        background-color: #65327B;
        text-align:center;  
        height: 30px;
        padding-top: 5px;
    }

    h3{
        font-family:"venus rising", "Lucida Grande", sans-serif;
        font-weight:bold;   
        font-size:16px;
        color: white;
        margin: 0;
        padding: 5px 0;
        text-align: center;
        background-color: #65327B;

        -webkit-border-radius: 2px 2px 0px 0px;
border-radius: 2px 2px 0px 0px;


    }

</style>


<?php 


class daniAPI{

    private $ch;

    public function __construct()
    {
        $this->ch = curl_init(); 
        curl_setopt($this->ch, CURLOPT_URL, 'http://www.daniweb.com/api/fetch'); 
        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); 
        curl_setopt($this->ch, CURLOPT_POST, true); 
    }

    public function search($member)
    {
        $options = array( 
            'id' => $member, 
            'type' => 'Member', 
            'is_username' => true
        ); 
        curl_setopt($this->ch, CURLOPT_POSTFIELDS, $options);       
        $output = json_decode(curl_exec($this->ch));        

        if(isset($output->error)){
            echo "We do not have a member by that name";
        }else{
            $defaultFields = array(
                'username' => '',
                'avatar' => 'http://static-cdn1.ustream.tv/i/channel/picture/9/1/3/2/9132320/9132320_unknown__user_1316740403,66x66,r:1.jpg', 
                'location' => 'Secret',
                'posts' => 0,
                'solvedthreads' => 0,
                'reputation' => 0,
                'endorsements' => 0,
                'homepage' => '',
                'joindate' => time(),
                'url' => '',
                'homepage' => ''
             );

            foreach($defaultFields as $k=>$v){
                $display[$k] = (!isset($output->$k)) ? $v : $output->$k;
            }
            extract($display);

            $days = ceil((time() - $joindate) / (24*60*60));
            if($homepage)$homepage =  " &bull; <a href='$homepage' target='_blank'>Homepage</a>";
            $ppd = number_format($posts/$days, 1); 
            $joindate =  date('d/m/Y', $joindate); // . " [$days days]";
echo <<<DW
            <div width="200" style="float:left;" class="main">
            <div class="topbit">
            <h3>$username</h3>
            <p class="big"><img src='$avatar' width="183" /></p>
            <p class="dw"><img src='dw.gif' width="183" /></p>
            </div>
            <div class="datarows">
            <table>

                <tr><td>Location:</td><td>$location</td></tr>
                <tr><td>More Info:</td><td><a href='$url' target='_blank'>Daniweb</a>$homepage</td></tr>
                <tr><td>Posts:</td><td>$posts</td></tr>
                <tr><td>Solved:</td><td>$solvedthreads</td></tr>
                <tr><td>Reputation:</td><td>$reputation</td></tr>
                <tr><td>Endorsements:</td><td>$endorsements</td></tr>
                <tr><td>Posts per Day:</td><td>$ppd</td></tr>
                <tr><td>Join Date:</td><td>$joindate</td></tr>
            </table>
            </div>
            </div>
DW;
        }
    }   

    public function close()
    {
        curl_close($this->ch); 
    }

}

$x = new daniAPI;
//$search = 'diafol';
if(isset($_POST['search']) && $_POST['search'] != ""){
    $x->search($_POST['search']);
}
if(isset($_POST['search2']) && $_POST['search2'] != ""){
    $x->search($_POST['search2']);
}
$x->close();
?>
<br style="clear:both;" />

<form method="post">
    <label>Member:</label>
    <input name="search" value="Dani" />
    <label>Member2:</label>
    <input name="search2" value="diafol"  />
     <input name="submit" type="submit" value="Search" />
</form>

//EDIT

I think it's stopped working now.

commented: Thanks for the code! I'm gonna playing around with it! +0

OK I think I finally have something I'm happy enough with to consider more stable.

Thanks for all of your positive feedback putting something together!! :)

OK, I feel comfortable enough with the current system to tell you that it should be safe to start building on it (no more constant changes).

I think it's stopped working now.

Sorry, I've been busy :) Can you update it using the latest API framework?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.