kegbot / kegbot-server Goto Github PK
View Code? Open in Web Editor NEWKegbot Server, the internet beer kegerator monitoring system.
Home Page: https://docs.kegbot.org/projects/kegbot-server/
License: MIT License
Kegbot Server, the internet beer kegerator monitoring system.
Home Page: https://docs.kegbot.org/projects/kegbot-server/
License: MIT License
Steps to reproduce:
Reloading the page manually and clicking settings again reloads the correct data into the form fields.
'Report a bug' link should link to github, not a dead page on kegbot.org
conrtib/twitter needs to be updated to use oauth and not try to use username / password from the obsolete Config table
I receive the following error while trying to migrate the recent changes...
File "/home/kegbot/kegbot/pykeg/src/pykeg/contrib/twitter/models.py", line 24, in
from pykeg.core import models as core_models
File "/home/kegbot/kegbot/pykeg/src/pykeg/core/models.py", line 36, in
from pykeg.core import stats
File "/home/kegbot/kegbot/pykeg/src/pykeg/core/stats.py", line 26, in
from pykeg.proto import models_pb2
File "/home/kegbot/kegbot/pykeg/src/pykeg/proto/models_pb2.py", line 1396, in
DESCRIPTOR.message_types_by_name['AuthenticationToken'] = _AUTHENTICATIONTOKEN
AttributeError: 'FileDescriptor' object has no attribute 'message_types_by_name'
Allow direct [re-]assignment of a token from within kegadmin.
Allow new tokens to be created from within kegadmin.
It would be nice to have C2DM support that can push event notifications to android devices. I've found this module, https://github.com/vokalinteractive/django-c2dm, it may be a decent start.
On the drinker detail page, the all sessions, by pints per session chart is not displaying the data correctly.
I am recieving an error when browsing to the kegweb account page. I also noticed that the login and logout pages cause the same error.
TemplateSyntaxError at /account/
TemplateSyntaxError at /accounts/logout/
TemplateSyntaxError at /accounts/login/
Caught AttributeError while rendering: 'NoneType' object has no attribute 'url'
The temperature and total beer poured charts are not displaying on the kegweb homepage.
pykeg.web.api.views.recent_events_html
AttributeError: 'WSGIRequest' object has no attribute 'kbsite'
Full details: http://kegbot.homeip.net/sentry/group/3
The number of known drinkers is showing as zero on the keg detail and session detail kegweb pages.
The bootstrapified session snapshot box is just unpleasant: The gradient is loud; the rounded corners don't match its surroundings; the volume box doesn't fit its contents, which are off-center; the number of drinker images varies wildly; etc.
Need to re-think this and make it look nicer.
Mike,
I'm running with the latest commits, and I noticed that the celery tasks for Twitter aren't being sent (Foursquare checkin is working).
Here's a log example:
Let me know if you need any thing else.
Cheers,
Geoff
On the first page view the units are displayed as their default (imperial) and the auto_units_metric cookie is set to false. However, after all following page views it gets changed to true and displays units in metric. When selecting the change to imperial in the footer it corrects the problem until the next page view, which will change it back to metric again.
I'm trying to minimize the number of api call the kegbot app I am working on makes. The one issue I've found is when it comes to keg details. I have to make a call to /kegs first to collect keg id values then poll /gets/id for each keg in order to get the name of the beer in the keg. The other useful listing is users, however looks like you just implemented that one.
Untappd.com is a social network that allows its users to "check in" to the beers that they are drinking. It would be super cool if kegbot could integrate with Untappd's API and check in for users automatically as beers are poured.
API docs are at http://untappd.com/api/docs/v3
Event box shows a broken image for guest pours.
Rendering all sessions seriously bogs down the keg and drinker stats pages. Limit how many are shown, eg by loading the data via the web api, paginating the results, and rendering client-side.
New statistic to maintain: drinker affinities.
Each drinker has a map of {drinker -> counter}. For each session, for each other drinker in the session, update the counter for that drinker.
Result should be a rank of all co-drinkers by frequency.
On the keg detail page, the all sessions list is out of order.
Example: http://kegbot.homeip.net/kegs/87
Since the start of the project guest pours always seem to be changing. When I have my kegbot running I get a decent number of guest pours, which I'm ok with, it just seems they need to be handled better. From what I can tell guest pours have no user assigned to the drink, there was a period where you were able to select a user to be the guest user if i recall correctly, as i have a decent chunk of drinks with the user set as guest rather than (none). The kegweb interface is really hit or miss when it comes to displaying guest pours, most of the time the drinker image is 404'd and empty, some of the links you can click and get actual pour and drinker stats, and some you cant. I'm sure this may have to do with using a database that has been used since the start. Perhaps some kind of migration is needed to clean it up and bring guest pours to a defined usage.
I like the idea of leaving the user null for guest drinks as it allows for easier changes down the road. I'd like the ability to have some kind of guest display options. A menu where: the guest display name can be changed, whether or not to display guest pours in kegweb recent activity (perhaps just collapse multiple pours to just one, to reduce an entire list of guest pours on home page), change the guest mugshot, and of course some guest related stats.
I've seen a crash similar to this 3 times now. I grabbed the output this time. This is with code pulled and installed from git repo this morning.
2011-12-20 10:59:45,473 ERROR (service-thread) Uncaught exception in thread service-thread. Stack trace:
2011-12-20 10:59:45,502 ERROR (service-thread) File "/usr/local/lib/python2.7/dist-packages/kegbot-0.8.3-py2.7.egg/pykeg/core/util.py", line 113, in run
2011-12-20 10:59:45,503 ERROR (service-thread) self.ThreadMain()
2011-12-20 10:59:45,504 ERROR (service-thread)
2011-12-20 10:59:45,504 ERROR (service-thread) File "/usr/local/lib/python2.7/dist-packages/kegbot-0.8.3-py2.7.egg/pykeg/core/kb_threads.py", line 124, in ThreadMain
2011-12-20 10:59:45,505 ERROR (service-thread) self._Step(timeout=0.5)
2011-12-20 10:59:45,506 ERROR (service-thread)
2011-12-20 10:59:45,507 ERROR (service-thread) File "/usr/local/lib/python2.7/dist-packages/kegbot-0.8.3-py2.7.egg/pykeg/core/kb_threads.py", line 129, in _Step
2011-12-20 10:59:45,508 ERROR (service-thread) self._ProcessEvent(event)
2011-12-20 10:59:45,509 ERROR (service-thread)
2011-12-20 10:59:45,509 ERROR (service-thread) File "/usr/local/lib/python2.7/dist-packages/kegbot-0.8.3-py2.7.egg/pykeg/core/kb_threads.py", line 156, in _ProcessEvent
2011-12-20 10:59:45,510 ERROR (service-thread) cb(event)
2011-12-20 10:59:45,511 ERROR (service-thread)
2011-12-20 10:59:45,512 ERROR (service-thread) File "/usr/local/lib/python2.7/dist-packages/kegbot-0.8.3-py2.7.egg/pykeg/core/manager.py", line 462, in HandleFlowUpdateEvent
2011-12-20 10:59:45,513 ERROR (service-thread) self._HandleFlowEnded(event)
2011-12-20 10:59:45,513 ERROR (service-thread)
2011-12-20 10:59:45,515 ERROR (service-thread) File "/usr/local/lib/python2.7/dist-packages/kegbot-0.8.3-py2.7.egg/pykeg/core/manager.py", line 491, in _HandleFlowEnded
2011-12-20 10:59:45,515 ERROR (service-thread) spilled=spilled)
2011-12-20 10:59:45,516 ERROR (service-thread)
2011-12-20 10:59:45,517 ERROR (service-thread) File "/usr/local/lib/python2.7/dist-packages/kegbot-0.8.3-py2.7.egg/pykeg/core/backend.py", line 302, in RecordDrink
2011-12-20 10:59:45,518 ERROR (service-thread) duration=duration, auth_token=auth_token, spilled=spilled)
2011-12-20 10:59:45,518 ERROR (service-thread)
2011-12-20 10:59:45,519 ERROR (service-thread) File "/usr/local/lib/python2.7/dist-packages/kegbot-0.8.3-py2.7.egg/pykeg/web/api/krest.py", line 251, in RecordDrink
2011-12-20 10:59:45,520 ERROR (service-thread) return self.DoPOST(endpoint, models_pb2.Drink(), post_data=post_data)
2011-12-20 10:59:45,521 ERROR (service-thread)
2011-12-20 10:59:45,521 ERROR (service-thread) File "/usr/local/lib/python2.7/dist-packages/kegbot-0.8.3-py2.7.egg/pykeg/web/api/krest.py", line 173, in DoPOST
2011-12-20 10:59:45,522 ERROR (service-thread) return self._FetchResponse(endpoint, out_msg, params=params, post_data=post_data)
2011-12-20 10:59:45,523 ERROR (service-thread)
2011-12-20 10:59:45,524 ERROR (service-thread) File "/usr/local/lib/python2.7/dist-packages/kegbot-0.8.3-py2.7.egg/pykeg/web/api/krest.py", line 195, in _FetchResponse
2011-12-20 10:59:45,525 ERROR (service-thread) response_data = urlopen(url, data=encoded_post_data, timeout=FLAGS.krest_timeout).read()
2011-12-20 10:59:45,525 ERROR (service-thread)
2011-12-20 10:59:45,526 ERROR (service-thread) File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
2011-12-20 10:59:45,526 ERROR (service-thread) return _opener.open(url, data, timeout)
2011-12-20 10:59:45,527 ERROR (service-thread)
2011-12-20 10:59:45,527 ERROR (service-thread) File "/usr/lib/python2.7/urllib2.py", line 394, in open
2011-12-20 10:59:45,527 ERROR (service-thread) response = self._open(req, data)
2011-12-20 10:59:45,528 ERROR (service-thread)
2011-12-20 10:59:45,528 ERROR (service-thread) File "/usr/lib/python2.7/urllib2.py", line 412, in _open
2011-12-20 10:59:45,529 ERROR (service-thread) '_open', req)
2011-12-20 10:59:45,529 ERROR (service-thread)
2011-12-20 10:59:45,529 ERROR (service-thread) File "/usr/lib/python2.7/urllib2.py", line 372, in _call_chain
2011-12-20 10:59:45,530 ERROR (service-thread) result = func(*args)
2011-12-20 10:59:45,530 ERROR (service-thread)
2011-12-20 10:59:45,530 ERROR (service-thread) File "/usr/lib/python2.7/urllib2.py", line 1201, in http_open
2011-12-20 10:59:45,531 ERROR (service-thread) return self.do_open(httplib.HTTPConnection, req)
2011-12-20 10:59:45,531 ERROR (service-thread)
2011-12-20 10:59:45,531 ERROR (service-thread) File "/usr/lib/python2.7/urllib2.py", line 1174, in do_open
2011-12-20 10:59:45,531 ERROR (service-thread) r = h.getresponse(buffering=True)
2011-12-20 10:59:45,532 ERROR (service-thread)
2011-12-20 10:59:45,532 ERROR (service-thread) File "/usr/lib/python2.7/httplib.py", line 1027, in getresponse
2011-12-20 10:59:45,533 ERROR (service-thread) response.begin()
2011-12-20 10:59:45,533 ERROR (service-thread)
2011-12-20 10:59:45,534 ERROR (service-thread) File "/usr/lib/python2.7/httplib.py", line 407, in begin
2011-12-20 10:59:45,534 ERROR (service-thread) version, status, reason = self._read_status()
2011-12-20 10:59:45,535 ERROR (service-thread)
2011-12-20 10:59:45,535 ERROR (service-thread) File "/usr/lib/python2.7/httplib.py", line 365, in _read_status
2011-12-20 10:59:45,535 ERROR (service-thread) line = self.fp.readline()
2011-12-20 10:59:45,536 ERROR (service-thread)
2011-12-20 10:59:45,536 ERROR (service-thread) File "/usr/lib/python2.7/socket.py", line 447, in readline
2011-12-20 10:59:45,537 ERROR (service-thread) data = self._sock.recv(self._rbufsize)
2011-12-20 10:59:45,537 ERROR (service-thread)
2011-12-20 10:59:45,537 ERROR (service-thread) Error was: <class 'socket.timeout'>: timed out
2011-12-20 10:59:45,538 ERROR (service-thread) Exiting thread.
2011-12-20 10:59:46,533 ERROR (watchdog-thread) Thread service-thread died unexpectedly
2011-12-20 10:59:46,563 INFO (alarmmanager-thread) got quit event, quitting
2011-12-20 10:59:46,564 INFO (net-thread) got quit event, quitting
2011-12-20 10:59:46,564 INFO (eventhub-thread) got quit event, quitting
2011-12-20 10:59:46,565 INFO (watchdog-thread) got quit event, quitting
2011-12-20 10:59:46,565 INFO (heartbeat-thread) got quit event, quitting
2011-12-20 10:59:46,633 INFO (kegnet) Stopping server
2011-12-20 10:59:47,535 ERROR (main) Watchdog thread exited, quitting
2011-12-20 10:59:48,537 INFO (main) Stopping any remaining threads
2011-12-20 10:59:48,538 INFO (main) Stopping all service threads.
2011-12-20 10:59:48,538 INFO (main) All service threads stopped.
2011-12-20 10:59:48,538 INFO (main) Kegbot stopped.
If I was more familiar with python I would take a crack at figuring it out, may look through the code later if I have time.
Thanks
-ray
Show for guests what we show for registered users.
Kegadmin is broken in the tip of tree, following the big css/layout changes. Fix it.
Several of the statistical charts are computed from session data directly, rather than cached stats data. Use the cached data.
In an all-guest rapid pour situation, the stream of individual anonymous pours has less meaning. It'd be nice to collapse it, at least on the front end.
Allow admin to change user assignment for drinks, including to/from anonymous pours.
Show a user's total pours as chart of volume by year.
Pouring a drink with the current tip of the tree causes kegbot_core to stop.
Error was: <class 'pykeg.web.api.krest.ServerError'>: Caused by: HTTP Error 500: INTERNAL SERVER ERROR
Full kegbot_core log: http://dpaste.com/673123/
Exception Type: TemplateSyntaxError at /
Exception Value: Caught NoReverseMatch while rendering: Reverse for 'pykeg.web.util.new_function' with arguments '(1L,)' and keyword arguments '{}' not found.
Full details: http://dpaste.com/602316/
When selecting a tap in the tap admin page it results in a template syntax error.
I'm assuming it has to do with the recent units changes, as the error is: Caught AttributeError while rendering: 'KegSize' object has no attribute 'Volume'
The error is also encountered while trying to view the KegSize entries in admin.
I noticed this Volume attribute was removed in commit: 97e8ab4
Sunday volumes are shown on Saturday, etc.
Charts are not sensitive to the user display preference (and in fact always display in imperial units). Fix it.
This is an odd one.
I can pour a drink from one tap with no issues. (drink registered, kegbot_core stays running), but when I pour a drink from my second tap kegbot_core stops with an error.
The kegbot_core log shows "2011-12-22 18:36:15,782 ERROR (service-thread) Error was: <class 'pykeg.web.api.krest.ServerError'>: Caused by: HTTP Error 500: INTERNAL SERVER ERROR"
The Senty message list shows a new error in pykeg.core.stats.RegisteredDrinkers -
AttributeError: 'RepeatedScalarFieldContainer' object has no attribute 'add'"
Location: /home/workbench/sandbox/kegbot-0.8.3/pykeg/src/pykeg/core/stats.py in RegisteredDrinkers, line 161
Thanks again for all the fixes, I know the risk I'm taking when running the tip of the tree.
Geoff
Testing the latest fixes, introduces a new error.
Page not found (404)
Request Method: GET
Request URL: http://kegbot.homeip.net/
No KegbotSite matches the given query.
Not Working:
http://kegbot.homeip.net/
http://kegbot.homeip.net/kegs/
http://kegbot.homeip.net/stats/
http://kegbot.homeip.net/kegadmin/
Working:
http://kegbot.homeip.net/account/
Thanks in advance for troubleshooting,
Geoff
New endpoint for registering a new account via the api.
I'm finally getting around to updating my kegbot server, it was a couple of months out of date. I'm currently installing on a fresh install of Ubuntu 12.04 Server.
During the install the setup halts with the following error...
Installed /home/ubuntu/kegbot/pykeg/src
Processing dependencies for kegbot==0.9.0
error: Installed distribution Django 1.4 conflicts with requirement Django>=1.2,<1.4
Trying to run the shell I get the following error...
ubuntu@domU-12-31-39-02-25-CF:/etc/apache2/sites-available$ kegbot-admin.py shell
Traceback (most recent call last):
File "/usr/local/bin/kegbot-admin.py", line 4, in <module>
from pkg_resources import require; require('kegbot==0.9.0')
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2711, in <module>
parse_requirements(__requires__), Environment()
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 588, in resolve
raise VersionConflict(dist,req) # XXX put more info here
pkg_resources.VersionConflict: (Django 1.4 (/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg), Requirement.parse('Django>=1.2,<1.4'))
Would it be possible to unify the colors that represent the different kegs that are displayed in the drinkers by volume chart?
Example: http://kegbot.homeip.net/session/2011-12-27/384/session-384
Note keg 94. It is green, blue or red depending on the drinker in that session.
The api always returns 100% apv for all beer types. I've double checked the values through admin and none of them are set as 100.
This can be seen through the api calls:
http://kegbot.goliathonline.com/api/kegs/7
http://kegbot.goliathonline.com/api/taps
I noticed when adding drinks from the Django admin interface, the stats are not all updated, only some. Even the recent activity isn't updated unless you regen stats.
[Edit 6/2013: previous subject: "Stats won't update if drinks are added manually"]
Hi Mike,
I'm getting an error when trying to browse to my kegweb homepage. Do you think this error could be caused by something wrong in my local configuration?
Exception Type: TemplateSyntaxError at /
Exception Value: Caught NoReverseMatch while rendering: Reverse for 'kb-home' with arguments '(u'Default',)' and keyword arguments '{}' not found.
Full details : http://kegbot.homeip.net/
This is pull of latest code. Probably has to do with all the default / multisite changes going on recently.
Can't get to certain views. And Kegbot core crashes when trying to start.
Here is a screenshot of the sentry error:
https://skitch.com/raytiley/gum84/kegbot-crash
Thanks
-ray
When running the kegbot-admin.py kb_regen_session command, I"m getting an error stopping the processing.
"Column 'site_id' cannot be null
Full details: http://dpaste.com/675559/
One of my drinkers used a hyphen in his username, this worked no problem prior to web api based kegweb. The following links now do not function:
http://kegbot.goliathonline.com/api/users/j-rome
http://kegbot.goliathonline.com/drinkers/j-rome
However, when viewing a session or keg page that mentions him, his data shows up just fine:
http://kegbot.goliathonline.com/session/2010-10-23/17/man-day
After switch to staticfiles the path to the unknown drinker image still uses site-media, which results in a missing image.
I've located the problem source here:
https://github.com/Kegbot/kegbot/blob/master/pykeg/src/pykeg/core/models.py#L129
I'm recieving several errors that tables do not exist. Looking at my database several of them do exist, ie: socialregistration_twitterprofile
Environment:
Request Method: GET
Request URL: http://kegbot.szechnet.com/account/connection/
Django Version: 1.4
Python Version: 2.7.3
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.humanize',
'django.contrib.markup',
'django.contrib.messages',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.staticfiles',
'django_extensions',
'bootstrapform',
'imagekit',
'pykeg.beerdb',
'pykeg.connections',
'pykeg.connections.foursquare',
'pykeg.connections.twitter',
'pykeg.connections.untappd',
'pykeg.contrib.soundserver',
'pykeg.core',
'pykeg.web',
'pykeg.web.api',
'pykeg.web.account',
'pykeg.web.charts',
'pykeg.web.kegweb',
'icanhaz',
'registration',
'socialregistration',
'socialregistration.contrib.twitter',
'socialregistration.contrib.facebook',
'socialregistration.contrib.foursquare',
'south',
'django_nose',
'sentry',
'sentry.client',
'djcelery',
'djkombu',
'raven.contrib.django',
'sentry',
'rjdj.djangotornado')
Installed Middleware:
('django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.gzip.GZipMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.transaction.TransactionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'pykeg.web.middleware.KegbotSiteMiddleware',
'pykeg.web.middleware.SiteActiveMiddleware',
'django.middleware.doc.XViewMiddleware',
'sentry.client.middleware.Sentry404CatchMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware')
Traceback:
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/contrib/auth/decorators.py" in _wrapped_view
20. return view_func(request, *args, **kwargs)
File "/home/ubuntu/kegbot/pykeg/src/pykeg/web/account/views.py" in connections
62. twitter_profile = sr_twitter_models.TwitterProfile.objects.get(user=user)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/models/manager.py" in get
131. return self.get_query_set().get(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/models/query.py" in get
361. num = len(clone)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/models/query.py" in __len__
85. self._result_cache = list(self.iterator())
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/models/query.py" in iterator
291. for row in compiler.results_iter():
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/models/sql/compiler.py" in results_iter
763. for rows in self.execute_sql(MULTI):
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/models/sql/compiler.py" in execute_sql
818. cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/backends/util.py" in execute
40. return self.cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/backends/mysql/base.py" in execute
114. return self.cursor.execute(query, args)
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py" in execute
174. self.errorhandler(self, exc, value)
File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py" in defaulterrorhandler
36. raise errorclass, errorvalue
Exception Type: DatabaseError at /account/connection/
Exception Value: (1146, "Table 'kegbot.twitter_twitterprofile' doesn't exist")
This case seems like the table prefix is the only thing that is wrong 'twitter_' rather than 'socialregistration_'
I also get a similar error for untappd.
Exception Type: DatabaseError at /admin/untappd/useruntappdlink/
Exception Value: (1146, "Table 'kegbot.untappd_useruntappdlink' doesn't exist")
However, I do not see any tables in the database for untappd.
I have run kegbot-admin.py migrate
several times and it always completes successfully.
I'm getting the following error when trying to run kegbot-admin.py kb_compress_temps
pykeg.core.models.MultipleObjectsReturned: get() returned more than one ThermoSummaryLog -- it returned 2! Lookup parameters were {'date': datetime.datetime(2011, 4, 2, 0, 0), 'period': 'daily'}
Full details: http://dpaste.com/604220/
In the recent activity list, each drink event is missing the drink size information. Also the url links to that drinker's page and the actual drink are not there anymore.
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.