├── .htaccess ├── README.md ├── getDeviations.js ├── getDeviations.php ├── javascript.php ├── php.php └── styles.css /.htaccess: -------------------------------------------------------------------------------- 1 | DirectoryIndex php.php -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # deviantART-API 2 | 3 | Use DeviantArt's RSS/XML feeds as a CMS to dynamically embed deviation galleries on your website. 4 | 5 | DeviantArt users can create Gallery Folders to organise their deviations (e.g. http://fu51on.deviantart.com/gallery/) 6 | 7 | This script returns the [data](#what-data-does-the-feed-provide) from all the deviations from the specified folder. 8 | 9 | ## What is the URL of the feed and its parameters? 10 | 11 | The RSS URL always begins with: `https://backend.deviantart.com/rss.xml` followed by some query parameters, e.g. https://backend.deviantart.com/rss.xml?q=gallery:fu51on/27123391 12 | 13 | [DeviantArt's RSS documentation](https://www.deviantart.com/developers/rss) only provides a couple of examples of how to construct RSS URLs. 14 | 15 | Here is an expanded list of query parameters: 16 | 17 | | Query params | Example | Description | 18 | | :- | :- | :- | 19 | | `q=by:[deviant name]` | `q=by:fu51on` | 20 | | `q=gallery:[deviant name]` | `q=gallery:fu51on` | 21 | | `q=gallery:[deviant name]/[gallery]` | `q=gallery:fu51on/27123391` | 22 | | `q=[search term]` | `q=frogs` | 23 | | `q=in:[category]` | `q=in:visual_art` | 24 | | `offset=[number]` | `offset=60` | 25 | | `order=[number]` | `order=5` | Order by newest | 26 | | `order=[number]` | `order=9` | Order by all-time popularity | 27 | | `limit=[number]` | `limit=10` | 1-60 | 28 | 29 | ## How can I get the Featured and Scraps galleries? 30 | 31 | Please see https://github.com/jamesl1001/deviantART-API/issues/4#issuecomment-1951384692 32 | 33 | ## What data does the feed provide? 34 | 35 | - title 36 | - link 37 | - permalink 38 | - date 39 | - keywords (doesn't seem to return anything at the moment) 40 | - rating 41 | - category 42 | - deviant's name 43 | - deviant's avatar 44 | - copyright 45 | - description 46 | - thumbnail (w: 150) 47 | - thumbnail (w: 300) 48 | - deviation 49 | 50 | ## Usage - PHP 51 | 52 | **Example** 53 | ``` 54 | 58 | ``` 59 | 60 | `getDeviations()` returns an array of objects containing all the data about each deviation from the provided gallery folder. 61 | 62 | You can use a foreach loop to extract the data you require: 63 | ``` 64 | 68 |

title; ?>

69 | 70 | 74 | ``` 75 | 76 | **Options** 77 | ``` 78 | getDeviations($url, $limit, $start); 79 | ``` 80 | 81 | `$url`: DeviantArt feed url `https://backend.deviantart.com/rss.xml?q=gallery:[deviant name]/[gallery]` 82 | 83 | `$limit`: Limit the number of deviations to be displayed 84 | 85 | `$start`: How many deviations to skip before displaying the rest 86 | 87 | ## Usage - Javascript 88 | 89 | `processDeviations()` is called once `getDeviations()` is complete which returns an array of objects containing all the data about each deviation from the provided gallery folder. 90 | 91 | You can use a for loop to extract the data you require: 92 | 93 | **Example** 94 | ``` 95 | 96 | 107 | ``` 108 | 109 | **Options** 110 | ``` 111 | getDeviations(url, limit, start); 112 | ``` 113 | 114 | `url`: DeviantArt feed url `https://backend.deviantart.com/rss.xml?q=gallery:[deviant name]/[gallery]` 115 | 116 | `limit`: Limit the number of deviations to be displayed, default is `null` 117 | 118 | `start`: How many deviations to skip before displaying the rest, default is 0 119 | -------------------------------------------------------------------------------- /getDeviations.js: -------------------------------------------------------------------------------- 1 | function getDeviations(url, limit, start) { 2 | var deviations = []; 3 | var limit = limit || null; 4 | var start = start || 0; 5 | 6 | let xhr = new XMLHttpRequest(); 7 | xhr.open('GET', 'https://backend.deviantart.com/rss.xml?q=gallery:fu51on/27123391'); 8 | xhr.send(); 9 | 10 | xhr.onload = function() { 11 | let json1 = xml2json(new DOMParser().parseFromString(xhr.response, 'text/xml')); 12 | let json2 = JSON.parse('{' + json1.slice(11)); 13 | let items = json2.rss.channel.item; 14 | 15 | for(var i = 0, l = items.length; i < l; i++) { 16 | if(i < start) { continue; } 17 | if(!!limit && i == start + limit) break; 18 | 19 | var object = {}; 20 | 21 | object.title = items[i].title; 22 | object.link = items[i].link; 23 | object.date = items[i].pubDate; 24 | object.desc = items[i]['media:description']['#text']; 25 | object.thumbS = items[i]['media:thumbnail']?.[0]['@url'] || null; 26 | object.thumbL = items[i]['media:thumbnail']?.[1]['@url'] || null; 27 | object.image = items[i]['media:content']?.['@url'] || null; 28 | object.rating = items[i]['media:rating']; 29 | object.category = items[i]['media:category']['#text']; 30 | object.categoryUrl = 'https://www.deviantart.com/' + object.category; 31 | object.deviantName = items[i]['media:credit'][0]['#text']; 32 | object.deviantAvatar = items[i]['media:credit'][1]['#text']; 33 | object.deviantUrl = items[i]['media:copyright']['@url']; 34 | object.copyright = items[i]['media:copyright']['#text']; 35 | 36 | deviations.push(object); 37 | } 38 | 39 | // async function is complete, move on 40 | processDeviations(deviations); 41 | }; 42 | } 43 | 44 | /* This work is licensed under Creative Commons GNU LGPL License. 45 | License: http://creativecommons.org/licenses/LGPL/2.1/ 46 | Version: 0.9 47 | Author: Stefan Goessner/2006 48 | Web: http://goessner.net/ 49 | */ 50 | function xml2json(e,n){var t={toObj:function(e){var n={};if(1==e.nodeType){if(e.attributes.length)for(var i=0;i1)n=t.escape(t.innerXml(e));else for(a=e.firstChild;a;a=a.nextSibling)n["#cdata"]=t.escape(a.nodeValue)}e.attributes.length||e.firstChild||(n=null)}else 9==e.nodeType?n=t.toObj(e.documentElement):alert("unhandled node type: "+e.nodeType);return n},toJson:function(e,n,i){var r=n?'"'+n+'"':"";if(e instanceof Array){for(var o=0,l=e.length;o1?"\n"+i+"\t"+e.join(",\n"+i+"\t")+"\n"+i:e.join(""))+"]"}else if(null==e)r+=(n&&":")+"null";else if("object"==typeof e){var a=[];for(var d in e)a[a.length]=t.toJson(e[d],d,i+"\t");r+=(n?":{":"{")+(a.length>1?"\n"+i+"\t"+a.join(",\n"+i+"\t")+"\n"+i:a.join(""))+"}"}else r+="string"==typeof e?(n&&":")+'"'+e.toString()+'"':(n&&":")+e.toString();return r},innerXml:function(e){var n="";if("innerHTML"in e)n=e.innerHTML;else for(var t=function(e){var n="";if(1==e.nodeType){n+="<"+e.nodeName;for(var i=0;i"}else n+="/>"}else 3==e.nodeType?n+=e.nodeValue:4==e.nodeType&&(n+="");return n},i=e.firstChild;i;i=i.nextSibling)n+=t(i);return n},escape:function(e){return e.replace(/[\\]/g,"\\\\").replace(/[\"]/g,'\\"').replace(/[\n]/g,"\\n").replace(/[\r]/g,"\\r")},removeWhite:function(e){e.normalize();for(var n=e.firstChild;n;)if(3==n.nodeType)if(n.nodeValue.match(/[^ \f\n\r\t\v]/))n=n.nextSibling;else{var i=n.nextSibling;e.removeChild(n),n=i}else 1==n.nodeType?(t.removeWhite(n),n=n.nextSibling):n=n.nextSibling;return e}};9==e.nodeType&&(e=e.documentElement);var i=t.toJson(t.toObj(t.removeWhite(e)),e.nodeName,"\t");return"{\n"+n+(n?i.replace(/\t/g,n):i.replace(/\t|\n/g,""))+"\n}"} -------------------------------------------------------------------------------- /getDeviations.php: -------------------------------------------------------------------------------- 1 | channel; 12 | $i = 0; 13 | $deviations = array(); 14 | 15 | foreach($channel->item as $item) { 16 | if($i < $start) { $i++; continue; } 17 | if(isset($limit) && $i == $start + $limit) break; 18 | 19 | $object = (object)array( 20 | "title" => $item->title, 21 | "url" => $item->link, 22 | "date" => $item->pubDate, 23 | "desc" => $item->children('media', true)->description, 24 | "thumbS" => ($item->children('media', true)->thumbnail) ? $item->children('media', true)->thumbnail[0]->attributes()->url : null, 25 | "thumbL" => ($item->children('media', true)->thumbnail) ? $item->children('media', true)->thumbnail[1]->attributes()->url : null, 26 | "image" => ($item->children('media', true)->content) ? $item->children('media', true)->content->attributes()->url : null, 27 | "rating" => $item->children('media', true)->rating, 28 | "categoryUrl" => $item->children('media', true)->category, 29 | "category" => $item->children('media', true)->category->attributes()->label, 30 | "deviantName" => $item->children('media', true)->credit[0], 31 | "deviantAvatar" => $item->children('media', true)->credit[1], 32 | "deviantUrl" => $item->children('media', true)->copyright->attributes()->url, 33 | "copyright" => $item->children('media', true)->copyright 34 | ); 35 | 36 | array_push($deviations, $object); 37 | $i++; 38 | } 39 | return $deviations; 40 | } -------------------------------------------------------------------------------- /javascript.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | deviantART-API 8 | 9 | 10 | 11 |

deviantART-API

12 |

https://github.com/jamesl1001/deviantART-API

13 |

PHP | JavaScript

14 |

Use DeviantArt's RSS/XML feeds as a CMS to dynamically embed deviation galleries on your website.

15 |

Feed: https://backend.deviantart.com/rss.xml?q=gallery:fu51on/27123391

16 | 17 |
18 | 19 | 20 | 57 | 58 | -------------------------------------------------------------------------------- /php.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | deviantART-API 8 | 9 | 10 | 11 |

deviantART-API

12 |

https://github.com/jamesl1001/deviantART-API

13 |

PHP | JavaScript

14 |

Use DeviantArt's RSS/XML feeds as a CMS to dynamically embed deviation galleries on your website.

15 |

Feed: https://backend.deviantart.com/rss.xml?q=gallery:fu51on/27123391

16 | 17 |
18 | 19 |
20 | $deviation): ?> 25 |
26 |
27 |

title; ?>

28 | <?= $deviations[$key]->title; ?> 29 |

Thumbnail src: 150px | 300px 30 |

31 |
32 |

Deviation Info

33 |

date; ?>

34 |

desc; ?>

35 |

Rating: rating; ?>

36 |

Category: category; ?>

37 |

By deviantName; ?>

38 | 39 |

copyright; ?>

40 |
41 |
42 | 45 |
46 | 47 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | -webkit-box-sizing: border-box; 3 | -moz-box-sizing: border-box; 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 9 | font-size: 14px; 10 | margin: 10px; 11 | } 12 | 13 | h2, p { 14 | margin-top: 0; 15 | } 16 | 17 | hr { 18 | width: 100%; 19 | height: 1px; 20 | background: #CCC; 21 | border: 0; 22 | margin: 20px 0 40px; 23 | float: left; 24 | } 25 | 26 | .deviation { 27 | width: 100%; 28 | max-width: 800px; 29 | background: #EEE; 30 | border-radius: 5px; 31 | box-shadow: 1px 1px 3px #CCC; 32 | margin-bottom: 40px; 33 | padding: 20px; 34 | overflow: hidden; 35 | } 36 | 37 | .col { 38 | width: 49%; 39 | float: left; 40 | } 41 | 42 | .col-p { 43 | margin-right: 1%; 44 | } 45 | 46 | .col-s { 47 | margin-left: 1%; 48 | } 49 | 50 | .deviation_image { 51 | width: 100%; 52 | box-shadow: 1px 1px 3px #999; 53 | margin-bottom: 10px; 54 | } --------------------------------------------------------------------------------