wagnerrp / pytmdb3 Goto Github PK
View Code? Open in Web Editor NEWPython interface to TheMovieDB.org v3 API
License: BSD 3-Clause "New" or "Revised" License
Python interface to TheMovieDB.org v3 API
License: BSD 3-Clause "New" or "Revised" License
>>> import tmdb3
>>> tmdb3.set_key(settings.TMDB_DEVELOPER_KEY)
>>> tmdb3.set_cache('null')
>>> m = tmdb3.Movie(3131)
>>> m
<Movie 'Gangs of New York' (2002)>
>>> m.crew
[<Crew 'Martin Scorsese','Director'>, <Crew 'Jay Cocks','Screenplay'>, ...
>>> c = m.crew[0]
>>> c
<Crew 'Martin Scorsese','Director'>
>>> c.job
u''
>>> c
<Crew 'Martin Scorsese',''>
>>> m.crew
[<Crew 'Martin Scorsese',''>, <Crew 'Jay Cocks','Screenplay'>, ...
Notice that c.job returns an empty string and afterwards, that Crew object's job permanently becomes an empty string.
This is based on 0.6.2.
Hi!
Since the TMDB API returns a 404 status error when looking up an ID that doesn't exist, the urllib2.urlopen() call in open() in request.py throws a HTTPError Exception, when it should throw a TMDBRequestError (Invalid id - The pre-requisite id is invalid or not found) if it correctly parses the JSON response.
Therefore, it seems that we cannot correctly distinguish between a connection error to TMDB and a normal 'not found' error.
I have fixed this locally using the following work-around, but I don't really like it:
In request.py/open(), the exception handling should be:
except urllib2.HTTPError, e:
if (e.code == 404):
return e.fp
raise TMDBHTTPError(str(e))
By forcing these errors to be parsed, the JSON will be read even if we got a 404 from the server. It seems safe as the API should always return a valid JSON response.
Regards!
New status codes have been added - https://www.themoviedb.org/documentation/api/status-codes
Actor with order="0" have empty string as return value.
mov = Movie(550) #Fight Club
cast=mov.cast
for person in cast:
print person.name, ' order: ', person.order, type(person.order)
Output:
Helena Bonham Carter order: 2 <type 'int'>
Meat Loaf order: 3 <type 'int'>
Zach Grenier order: 4 <type 'int'>
Richmond Arquette order: 5 <type 'int'>
David Andrews order: 6 <type 'int'>
Rachel Singer order: 7 <type 'int'>
Holt McCallany order: 8 <type 'int'>
Eion Bailey order: 9 <type 'int'>
Jared Leto order: 10 <type 'int'>
Peter Iacangelo order: 11 <type 'int'>
Edward Norton order: <type 'unicode'>
Thanks for your works.
When you use set_cache('null') you get the following error:
/tmdb3/cache_engine.py", line 17, in getitem
return self._engines[key]
KeyError: 0
now that the caching is configurable, it works great for the first nothing in cache but the second hit (even if it's the same title) errors. this is with and without using the cache configuration..
I also couldn't easily configure the cache until I added it to the import in tmdb_api.py mimicing how you were using set_api
I apologize for not having the exact errors, I forgot to post this before leaving the house.
FileCacheObjects are accumulated and system memory usage keeps on increasing as api calls are made in a python process.
Hi,
looping through the response of "Gravity" will throw an "list index out of range" exception. This also happens with movies like "Imagine" or "Mamma Mia!". I am sure about the cause of this problem.
I am looking forward to your answer and appreciate your help
Ben
code example:
response = searchMovie("Gravity")
print "length", len(response)
for x in xrange(0, len(response)):
print "%d title: %s" % (x, response[x].title)
Output:
length 16
0 title: Gravity
1 title: Gravity
2 title: Gravity
3 title: Nazi Ufos: How They Fly - Exposing the German Tesla Anti-Gravity & Free Energy Program
4 title: Defying Gravity
5 title: Beyond Gravity
6 title: Defying Gravity
7 title: Laws of Gravity
8 title: Anti Gravity Unhinged
9 title: The Division of Gravity
10 title: Gravity Is My Enemy
11 title: Gravity was everywhere back then
12 title: What on Earth is Wrong with Gravity
13 title: Love and Debate
14 title: Way of Life
Traceback (most recent call last):
File "exampleError.py", line 24, in
print "%d title: %s" % (x, response[x].title)
File "/Library/Python/2.7/site-packages/tmdb3/pager.py", line 70, in getitem
return self._data[index]
IndexError: list index out of range
I'm getting:
from tmdb3 import searchMovie
Traceback (most recent call last):
File "<pyshell#4>", line 1, in
from tmdb3 import searchMovie
File "C:\Python34\lib\site-packages\tmdb3__init__.py", line 3, in
from tmdb_api import Configuration, searchMovie, searchMovieWithYear,
ImportError: No module named 'tmdb_api'
Add support for checking the HTTP ETAG attribute in the response header to allow more intelligent caching.
Hi,
when querying information about cast or crew I stumbled over some strange behavior:
If I access the Cast.dayofbirth field first, a query to Cast.order or Cast.character will return an empty string. Other fields like name are still accessible and will return correct values.
If I turn around the access order and query Cast.dayofbirth last everything works as expected.
I saw the same behavior when working with the crew objects. It seems that fields from the Cast or Crew classes get lost after an access to dayofbirth. The fields of the parent class Person remain intact.
Python 2.7.3 (default, Apr 24 2012, 00:00:54)
[GCC 4.7.0 20120414 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import tmdb3
>>> tmdb3.set_key('...')
>>> movie = tmdb3.Movie.fromIMDB('tt1001526')
>>> print movie.cast[0].dayofbirth
1967-07-16
>>> print movie.cast[0].character
>>> print movie.cast[0]
<Cast 'Will Ferrell' as ''>
>>> print movie.cast[0].order
>>> print movie.cast[0].name
Will Ferrell
>>> movie = tmdb3.Movie.fromIMDB('tt1001526')
>>> print movie.cast[0].character
Megamind (voice)
>>> print movie.cast[0].dayofbirth
1967-07-16
>>>
Git commit id of tmdb3: 6e7725d
Please look at http://ubuntuforums.org/showthread.php?t=2212035
"But, I think I might be onto something ... turns out that when there's only one movie with the name (I assume it parses the filename and treats it like a search term), then it doesn't return anything, but if there's only one name, then it picks up the metadata just fine. If that's the case, I read that there should be a listing of found files and you can select the one you want. "
Perhaps I'm misunderstanding how this is supposed to work, but it looks like all request parameters are encoded using the system locale encoding. (https://github.com/wagnerrp/pytmdb3/blob/master/tmdb3/request.py#L70) This causes problems when the system locale cannot encode all the charaters in the parameters, plus, I have no idea how tmdb is expected to know what encoding you have used to encode the parameters, I suspect it should be using a constant encoding defined by the tmdb api.
Portion of a relevant traceback:
File "/usr/local/lib/python2.7/dist-packages/flexget/plugins/api_tmdb.py", line 293, in lookup
result = _first_result(tmdb3.tmdb_api.searchMovie(title.lower(), adult=True, year=year))
File "/usr/local/lib/python2.7/dist-packages/tmdb3/tmdb_api.py", line 128, in searchMovie
return MovieSearchResult(Request('search/movie', **kwargs), locale=locale)
File "/usr/local/lib/python2.7/dist-packages/tmdb3/request.py", line 71, in __init__
kwargs[k] = locale.encode(v)
File "/usr/local/lib/python2.7/dist-packages/tmdb3/locales.py", line 110, in encode
return dat.encode(self.encoding)
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 0-13: ordinal not in range(256)
Downstream ticket: http://flexget.com/ticket/2392
I can't seem to find anything in the API that lets me specify a location I'm interested in when searching. A movie will be released at a different time depending on, say, a lat-long tuple. The "releasedate" field seems to always be indicating the US release date? Is there a way I can get the release date of a movie for, say, UK or Brazil?
A traceback from our software when looking up a movie which has an alternate title with a non-ascii country name. The code calls str(country) which will fail for any non-ascii country name. If country codes are meant to be ascii only, the library should throw out the invalid result. If not, it should always be dealing with the result as unicode, and never as bytes.
The movie causing this traceback is Rocky (tt0075148).
Traceback (most recent call last):
File "C:\Users\chase.sterling\PycharmProjects\Flexget\flexget\task.py", line 420, in __run_plugin
return method(*args, **kwargs)
File "C:\Users\chase.sterling\PycharmProjects\Flexget\flexget\event.py", line 21, in __call__
return self.func(*args, **kwargs)
File "C:\Users\chase.sterling\PycharmProjects\Flexget\flexget\plugins\output\dump.py", line 83, in on_task_output
dump(undecided, task.options.debug, eval_lazy, trace)
File "C:\Users\chase.sterling\PycharmProjects\Flexget\flexget\plugins\output\dump.py", line 35, in dump
value = entry[field]
File "C:\Users\chase.sterling\PycharmProjects\Flexget\flexget\entry.py", line 270, in __getitem__
return result()
File "C:\Users\chase.sterling\PycharmProjects\Flexget\flexget\entry.py", line 43, in __call__
result = func(self.entry, self.field)
File "C:\Users\chase.sterling\PycharmProjects\Flexget\flexget\plugins\metainfo\tmdb_lookup.py", line 59, in lazy_loader
imdb_id=imdb_id)
File "C:\Users\chase.sterling\PycharmProjects\Flexget\flexget\utils\database.py", line 25, in wrapper
result = func(*args, **kwargs)
File "C:\Users\chase.sterling\PycharmProjects\Flexget\flexget\plugins\api_tmdb.py", line 289, in lookup
ApiTmdb.get_movie_details(movie, session)
File "C:\Users\chase.sterling\PycharmProjects\Flexget\flexget\plugins\api_tmdb.py", line 331, in get_movie_details
movie.update_from_object(result)
File "C:\Users\chase.sterling\PycharmProjects\Flexget\flexget\plugins\api_tmdb.py", line 121, in update_from_object
if len(update_object.alternate_titles) > 0:
File "C:\Users\chase.sterling\PycharmProjects\Flexget\lib\site-packages\tmdb3\util.py", line 152, in __get__
self.poller.__get__(inst, owner)()
File "C:\Users\chase.sterling\PycharmProjects\Flexget\lib\site-packages\tmdb3\util.py", line 80, in __call__
self.apply(req.readJSON())
File "C:\Users\chase.sterling\PycharmProjects\Flexget\lib\site-packages\tmdb3\util.py", line 89, in apply
setattr(self.inst, v, data[k])
File "C:\Users\chase.sterling\PycharmProjects\Flexget\lib\site-packages\tmdb3\util.py", line 223, in __set__
data.sort()
File "C:\Users\chase.sterling\PycharmProjects\Flexget\lib\site-packages\tmdb3\tmdb_api.py", line 282, in __lt__
return (self.country == self._locale.country) \
File "C:\Users\chase.sterling\PycharmProjects\Flexget\lib\site-packages\tmdb3\locales.py", line 44, in __eq__
return (id(self) == id(other)) or (str(self) == str(other))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)
It seems the freebsd package is being selected by pip on non-freebsd systems and causing install errors. Downstream ticket: http://flexget.com/ticket/2788
I get the following error:
tmdb3.set_key('99999999999999999999999999999')
Traceback (most recent call last):
File "", line 1, in
File "tmdb3/request.py", line 33, in set_key
raise TMDBKeyInvalid("Specified API key must be 128-bit hex")
tmdb3.tmdb_exceptions.TMDBKeyInvalid: Specified API key must be 128-bit hexThe key being supplied is identical to the key listed in the web site. It also being accepted by the old tmdb api without issue.
When looping through a list of movies, I'm running this code (where movie
is a Movie):
movie.poster.geturl(size='w154')
But I get this error, even when only running .geturl()
:
Exception Type: AttributeError
Exception Value: 'unicode' object has no attribute 'geturl'
Thanks for the awesome API!
TMDB's doc says:
Request Rate Limiting
We do enforce a small amount of rate limiting. Please be aware that should you exceed these limits, you will receive a 503 error.30 requests every 10 seconds per IP
Maximum 20 simultaneous connections per IP
Given that it's so simple to use tmdb3 and that it makes requests to TMDB pretty much seamlessly just by accessing properties on an object, is there a way to limit the rate of requests sent to the TMDB backends?
Here's a code example to illustrate:
people = tmdb3.searchPerson("brad pitt") # calls backend
for person in people:
for role in person.roles: # calls backend
print role.releases # calls backend
Here the 30QPS is impossible to enforce on the client side. The cache may help reduce the number of queries but the problem is still there.
What's the best option?
Thanks!
Example search Star Trek for 'search/tv'.
f.i. for the Star Trek TOS it is: https://www.themoviedb.org/tv/253-star-trek/season/3
This metod searchSeries(Star Trek) not found result .
Please help.
Running this python script shows what I mean.
from tmdb3 import searchMovie, Movie, set_key, set_locale
set_key('xxxxxxxxx')
set_locale()
results = searchMovie('the tenant')
print list(results)
item = results[1]
print 'Originaltitle: ' + item.originaltitle
print 'Title: ' + item.title
print 'Runtime: ' + item.runtime
print 'IMDB id: ' + item.imdb
print 'Overview: ' + item.overview
print list(results)
The second time the search results are printed "The Tenant (1976)" becomes "Le locataire (1976)". When any of Runtime, IMDB, or Overview are printed this happens. If just the Title and/or Originaltitle is printed by itself, it doesn't.
api 2.1 added the ability to look up a movie directly with tt#. 3 removed the search but you can still look up the movie directly.
testing=Movie('tt1232829")
both return the imdb id and id does not return the tmdb id:
print testing.id
print testing.imdb
tmdb3 rocks, so it should be on PiPY. (pip install tmdb3)
Request to make TMDb3 thread safe.
I think one part requires not using one specific cache file but using a seperate file for each lookup.
Btw, awesome package! Thanks for your work.
when trying to get the language of an image you get the following error:
, line 45, in call
raise RuntimeError('Poller object called without a source function')
RuntimeError: Poller object called without a source function
Does the "adult" parameter do anything when searching?
I need the new TV related stuff and since pypi reports 0.7.0 as the latest tmdb3 version (https://pypi.python.org/pypi/tmdb3) I'm trying to upgrade my python setup, but both pip and easy_install, with --upgrade option, are stuck on the 0.6.17. they say it's the latest version available. is it only happening to me?
Is it possible to get all of the TV-series in the database as a list? I mean names of the shows and some basic info.
This is the python API returning English overview and title information while there was actually no metadata available for Russian.
This is the TMDb page for the movie, stating that there is no information filled in yet for Russian metadata.
It seems that the fallthrough does not prevent the API from returning metadata from a language different than the locale that has been set.
When name searching with: nausicaä of the valley of the wind 1984
You get teh follwing error:
tmdb3/request.py", line 58, in init
urllib.urlencode(kwargs))
File "/usr/lib/python2.7/urllib.py", line 1311, in urlencode
v = quote_plus(str(v))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 7: ordinal not in range(128)
Probaply a copy and paste mistake
Please release this package like pytmdb3-1.0.0.tar.gz
Thanks.
pip install tmdb3
I know the above may seem obvious but I reckon it'd help the less experienced among us. I've worked it out myself but now but I reckon having them up front and centre would be good for others.
Anyway - Fantastic library and very much appreciate your work!! :)
The Datapoint definition allows a handler callable to be supplied, for which the data returned by queries is passed through. Due to the manner datapoints are defined, and Python's lack of prototypes, this handler must be fully defined in the namespace at the point the Datapoint is created. This leads to circular dependency issues where two classes must be defined before each other, such as the Studio class having a 'parent' attribute that back-references to itself during its own creation. Right now, this is worked around by using a lambda function, however that prevents the locale passthrough from happening properly.
dir(movie2.poster)
['_InitArgs', 'class', 'delattr', 'dict', 'doc', 'eq', 'format', 'getattribute', 'gt', 'hash', 'init', 'lt', 'metaclass', 'module', 'new', 'nonzero', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', '_data', '_lang', '_locale', '_populate', '_session', 'aspectratio', 'filename', 'geturl', 'height', 'language', 'sizes', 'width']
movie2.poster.language
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.7/dist-packages/tmdb3/util.py", line 143, in get
self.poller.get(inst, owner)()
File "/usr/local/lib/python2.7/dist-packages/tmdb3/util.py", line 61, in call
raise RuntimeError('Poller object called without a source function')
RuntimeError: Poller object called without a source function
we won't get into why I found this but fcntl is not available on windows so the import fcntl errors out.
As described, dict 'Release' must contain:
Release:
string - certification
string - country
datetime - releasedate
But (in python):
mov = Movie(550) print mov.releases
Output:
{u'FR': <Release FR, 1999-11-10 00:00:00>, u'DE': <Release DE, 1999-11-11 00:00:00>, u'TR': <Release TR, 1999-12-10 00:00:00>, u'US': <Release US, 1999-10-15 00:00:00>, u'GB': <Release GB, 1999-11-12 00:00:00>, u'BR': <Release BR, 1999-07-12 00:00:00>}
There is no certification data.
I'm not really sure if this is an intended behaviour.
I think "None" would be more adequate here.
Hi,
independently of the locale set, the primary release date of a specific movie gets returned.
This behavior can be seen if you set the locale to 'DE' and fetch "Wir sind die Millers" (original title: We're the Millers). The returned release date is always "2013-08-07" which is the primary one. It is supposed to be "2013-08-28" though.
I am looking forward to your answer and appreciate your help
Ben
code example:
set_locale('de', 'DE')
response = searchMovie("Wir sind die Millers")
for movie in response:
print movie.releasedate //will return 2013-08-07
In tmdb_api.py, Person._populate_credits uses /person/${id}/credits but looking at the docs, it looks like this API is gone or at least it's not documented anymore: http://docs.themoviedb.apiary.io/#reference/people/personidmoviecredits
I made a few requests and noticed it seems to be equivalent to (the new) /person/${id}/movie_credits.
Would it be possible to use /combined_credits instead? I think /combined_credits = /movie_credits + /tv_credits.
Obviously the best would be to support all 3 APIs, but that's a stretch.
Thanks!
Looks like a pip install now causes a crash due to README.md not being included in the package.
Downloading/unpacking tmdb3 (from FlexGet==1.2.265.dev)
Downloading tmdb3-0.7.2.tar.gz
Running setup.py (path:/home/travis/virtualenv/python2.6.9/build/tmdb3/setup.py) egg_info for package tmdb3
Traceback (most recent call last):
File "<string>", line 17, in <module>
File "/home/travis/virtualenv/python2.6.9/build/tmdb3/setup.py", line 9, in <module>
with open('README.md') as f:
IOError: [Errno 2] No such file or directory: 'README.md'
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 17, in <module>
File "/home/travis/virtualenv/python2.6.9/build/tmdb3/setup.py", line 9, in <module>
with open('README.md') as f:
IOError: [Errno 2] No such file or directory: 'README.md'
The Person, Studio, Movie, and Collection queries all return some form of image, but only provide the filename. There is no mechanism to query additional information for those images, so attempts to access those datapoints will result in an error. For images coming from movies and people, this information can be accessed through other queries available to the parent, so some method could be devices to properly populate those objects.
The day of birth is not necessarily formatted as "YYYY-MM-DD". http://www.themoviedb.org/person/10295, for instance, contains only the year which causes process_date() to fail.
Python 2.7.3rc2 (default, Apr 22 2012, 22:30:17)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import tmdb3
>>> tmdb3.set_key('7243d57358963cb7388deb6d1b0f50f5')
>>> person = tmdb3.Person(10295)
>>> print person.name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "tmdb3/util.py", line 143, in __get__
self.poller.__get__(inst, owner)()
File "tmdb3/util.py", line 77, in __call__
self.apply(req.readJSON())
File "tmdb3/util.py", line 86, in apply
setattr(self.inst, v, data[k])
File "tmdb3/util.py", line 148, in __set__
value = self.handler(value)
File "tmdb3/util.py", line 163, in <lambda>
self.handler = lambda x: handler(x)
File "tmdb3/tmdb_api.py", line 67, in process_date
return datetime.date(*[int(x) for x in datestr.split('-')])
TypeError: Required argument 'month' (pos 2) not found
>>>
Hi, I am working on a project that must communicate with themoviedb to retrieve some data and would like to use pytmdb3. The problem is the project I'm working on is in python 3. Do you plan on porting the code to py3k? Any idea if such task would be too hard? It would be great not to start from scratch :)
Hi,
I am using PyTMDB3 and for the most part successfully, although I have 1 problem. I have the following code:
import os
from tmdb3 import searchMovie
from tmdb3 import set_key
set_key('<APIKEY>')
for path, subdirs, files in os.walk(r'/media/Movies'):
files = [ file for file in files if not file.endswith( ('.nfo','.tbn','.jpg','.xml','.srt') ) ]
for filename in files:
fname = str(os.path.splitext(filename)[0])
res = searchMovie(fname)
print (res[0])
It goes through my movies and prints out the movie name found on tmdb. It works although there are 5 movies in which it doesnt work and I get an error and I cant figure out why.
The movies are Madagascar, Robin Hood, The Grey, The Watch and Zombieland. I can see that they are all on tmdb so am not sure why it isnt finding them.
The error is:
Traceback (most recent call last):
File "scan.py", line 14, in
res = searchMovie(fname)
File "/usr/local/lib/python2.7/dist-packages/tmdb3/tmdb_api.py", line 121, in searchMovie
return MovieSearchResult(Request('search/movie', **kwargs), locale=locale)
File "/usr/local/lib/python2.7/dist-packages/tmdb3/tmdb_api.py", line 148, in init lambda x: Movie(raw=x, locale=locale))
File "/usr/local/lib/python2.7/dist-packages/tmdb3/pager.py", line 101, in init super(PagedRequest, self).init(self._getpage(1), 20)
File "/usr/local/lib/python2.7/dist-packages/tmdb3/pager.py", line 56, in __init__self._data = list(iterable)
File "/usr/local/lib/python2.7/dist-packages/tmdb3/pager.py", line 108, in _ge tpageyield self._handler(item)
File "/usr/local/lib/python2.7/dist-packages/tmdb3/tmdb_api.py", line 148, in lambda x: Movie(raw=x, locale=locale))
File "/usr/local/lib/python2.7/dist-packages/tmdb3/util.py", line 350, in __call__obj._populate.apply(kwargs['raw'], False)
File "/usr/local/lib/python2.7/dist-packages/tmdb3/util.py", line 83, in apply if (k in
TypeError: argument of type 'NoneType' is not iterable
Thanks for any help.
Jay
Excellent wrapper.
The cache directory appears to be hard coded, it would be great if we could set the cache directory.
when using backdrops, if _populate_images sends arg language, you do not get any backdrops in the list.
Since so many people upload backdrops without a language, the backdrops list is almost always empty when specifying a language. I think backdrops list should contain both types of backdrops or at least have an option for it. Right now, using a language effectively breaks backdrop support.
Hello,
I'm considering to use this API wrapper for a small application but I did not find any information about its licence.
Could you please tell me under what licence it is released ?
Version: tmdb3 0.6.17 installed with pip
To reproduce:
res = tmdb3.searchMovie("Despicable Me", year=2010)
for m in res:
print m.title
Error:
for m in data:
File "/usr/local/lib/python2.7/dist-packages/tmdb3/pager.py", line 25, in next
return self._parent[self._index]
File "/usr/local/lib/python2.7/dist-packages/tmdb3/pager.py", line 70, in __getitem__
return self._data[index]
IndexError: list index out of range
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.