Giter VIP home page Giter VIP logo

plex-music-rating-sync's Introduction

plex-music-rating-sync

Plex Agents do not read music ratings when importing music files. This makes sense from a server-side-of-view. You don't want all users to have the same ratings or playlists. Every user should be able to set his / her own ratings and collect his favorite songs in playlists.

This project aims to provide a simple sync tool that synchronizes the track ratings and playlists with a specific PLEX user account and server.

Features

  • synchronize: track ratings, playlists (not automatically generated)
  • supported local media players: MediaMonkey
  • dry run without applying any changes
  • automatically or manually resolve conflicting track ratings
  • logging

Requirements

Installation

  1. Clone this repository git clone [email protected]:patzm/plex-music-rating-sync.git
  2. cd plex-music-rating-sync
  3. Install all requirements pip3.6 install -r requirements.txt

How to run

The main file is sync_ratings.py. Usage description: Note: default values of command line arguments can be provided by editing config.ini

usage: sync_ratings.py [-h] [--dry] [--reverse] [--log LOG] [--passwd PASSWD] [--token TOKEN]
                       [--sync ITEM] [--player PLAYER] --server SERVER --username USERNAME

Synchronizes ID3 music ratings with a Plex media-server

required arguments:
  --server SERVER      The name of the plex media server
  --username USERNAME  The plex username
  
optional arguments:
  -h, --help           show this help message and exit
  --dry                Does not apply any changes
  --reverse            Reverses ratings synchronization from Plex to local player 
  --sync               Selects which items to sync: one or more of: tracks, playlists [default is tracks]
  --log LOG            Sets the logging level
  --passwd PASSWD      The password for the plex user. NOT RECOMMENDED TO USE!
  --token TOKEN        Plex API token.  See https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/ for information on how to find your token
  --player PLAYER      Media player to synchronize with Plex [default is MediaMonkey]

Start the synchronization: ./sync_ratings.py --server <server_name> --username <[email protected]|user_name> Using the --dry flag in combination with --log DEBUG is recommended to see what changes will be made.

Current issues

  • the PlexAPI seems to be only working for the administrator of the PMS.
  • playlist synchronization from Plex to local player not implemented

Potential next features

With the current state I have completed all functionality I desired to have. Consequently I will not continue development unless you request it. I welcome anyone to join the development of this little cmd-line tool. Just open a new issue, post a pull request, or ask me to give you permissions for the repository itself.

These are a few ideas I have for features that would make sense:

  • setup routine
  • bi-directional sync
  • parallelization
  • better user-interaction with nicer dialogs
  • iTunes synchronization?

References

PlexAPI simplifies talking to a PMS.

This project uses the MediaMonkey scripting interface using Microsoft COM model. An introduction can be found here. The relevant model documentation is available here.

plex-music-rating-sync's People

Contributors

patzm avatar smilerz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

plex-music-rating-sync's Issues

Python TypeError

Again, thank you for your efforts on this, and I hope this isn't user error, but after downgrading to MediaMonkey to 4.1.2, I made it further than with my other issue. but started getting the following error with Python 3.9

line 63, in get_normed_rating
    if rating < 0:
TypeError: '<' not supported between instances of 'NoneType' and 'int'

After some unintelligent banging around, I changed (in MediaPlayer.py)

	def get_normed_rating(self, rating):
		if rating < 0:
			rating = 0
		return rating / self.rating_maximum

To

	def get_normed_rating(self, rating):
                if rating is None:
                          rating = 0
                      elif rating < 0:
                          rating = 0
		return rating / self.rating_maximum

And was able to successfully update my ratings! I have found no other software on the web that can do this, so thanks again. I have no idea what the potential ramification of my edit are, but they seemed to work.

Unrelated, I also encountered your stated bug with python-plexapi not updating non-admin users. I poked around and found this issue, where they reference this code:

from plexapi.server import PlexServer
from plexapi.myplex import MyPlexAccount
import requests

PLEX_URL = "https://127.0.0.1:32400"
PLEX_TOKEN = "YOUR ADMIN TOKEN"

sess = requests.Session()
sess.verify = False
plex = PlexServer(PLEX_URL, PLEX_TOKEN, session=sess)
account = MyPlexAccount(token=PLEX_TOKEN)
user_account = account.user('Guest')
token = user_account.get_token(plex.machineIdentifier)
user_connection = PlexServer(PLEX_URL, token, session=sess)
print(user_connection)
# You can now use "user_connection" as you would the "PlexServer"
print([x for x in user_connection.library.section("Movies").search(unwatched=True)])

I don't know if it's actually relevant, but the discussion seemed to indicate that non-admin user access could be achieve this way (?) I didn't know enough on where to try the changes. I was guessing around line 267 of MediaPlayer.py, and then maybe something to do with:

token = user_account.get_token(plex.machineIdentifier)

But I'm out of my element. Thanks again. I'm already very happy to have my favorite songs easily identifiable in Plex.

Encoding Error in Debug Log

When the song title uses a character that can't be encoded, the following error is raised when the debug message is written to sync_ratings.log:

--- Logging error ---
Traceback (most recent call last):
File "C:\Users\jim\miniconda3\envs\syncratings\lib\logging_init_.py", line 1082, in emit
stream.write(msg + self.terminator)
File "C:\Users\jim\miniconda3\envs\syncratings\lib\encodings\cp1252.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u2010' in position 92: character maps to
Call stack:
File "G:\Portable Installations\python\plex-music-rating-sync\sync_ratings.py", line 180, in
sync_agent.sync()
File "G:\Portable Installations\python\plex-music-rating-sync\sync_ratings.py", line 109, in sync
self.sync_tracks()
File "G:\Portable Installations\python\plex-music-rating-sync\sync_ratings.py", line 131, in sync_tracks
if pair.match(): matched += 1
File "G:\Portable Installations\python\plex-music-rating-sync\sync_pair.py", line 131, in match
self.logger.debug('Found match with score {} for {}: {}'.format(
Message: 'Found match with score 100.0 for American Hi‐Fi - American Hi‐Fi - I’m a Fool: American Hi‐Fi - American Hi‐Fi - I’m a Fool'
Arguments: ()

This can be corrected by making the following change to line 58 of sync_ratings.py (to specify the encoding of the file being written to):

fh = logging.FileHandler(filename='sync_ratings.log', encoding='utf-8', mode='w')

No Rating Found in Plex?

Hi,

This tool is exactly what I was looking for! I'm running on a Win10 laptop with the most recent MediaMonkey. My Plex server runs on an Ubuntu box on my local network. I run the script, and it appears to work -- but finds no ratings to sync. According to Plex, I have over 1000 songs rated. I have no songs rated in MM. Here's my output:

G:\plex-music-rating-sync>.\sync_ratings.py --log DEBUG --dry --server [myserver] --user [myusername] --token [mytoken]
[08:26:47] INFO: Connecting to local player MediaMonkey
[08:26:47] INFO: Connecting to the Plex Server [myservername] with username [myusername].
[08:26:49] INFO: Connecting to remote player PlexPlayer on the server [myservername]
[08:26:49] INFO: Successfully connected
[08:26:49] INFO: Looking for music libraries
Found multiple music libraries:
[25]: Comedy
[21]: Music
[22]: Music (Christmas)
[24]: Music (Classical)
Select the library to sync with: 21
[08:26:52] INFO: Starting to sync track ratings from PlexPlayer to MediaMonkey
[08:26:52] DEBUG: Executing query [Rating > 0] against MediaMonkey
[08:26:52] INFO: Reading tracks from the MediaMonkey player
[08:26:52] INFO: Attempting to match 0 tracks
[08:26:52] INFO: Matching source tracks with destination player
[08:26:52] INFO: Matched 0/0 tracks
[08:26:52] INFO: Running a DRY RUN. No changes will be propagated!
[08:26:52] INFO: Synchronizing 0 matching tracks without conflicts
[08:26:52] INFO: 0 pairs have conflicting ratings

It seems like it made a successful connection to Plex - the list of libraries it asks me to choose from is correct.

I have recently (within the past two weeks) completely rebuilt both the Plex and MM libraries.

I suspect I'm doing something wrong with MM...I'm not very familiar with it, and only installed it to use this script to write the rating tags to the mp3 files. Do you have any idea what I may be doing wrong? Or how I can track it down on my own?

Thanks very much for this tool and any help you can provide!

Jim

providing a password as a CLI argument confuses servername and username

I believe I have everything set up, but when I try to sync from the command prompt, I receive the following message:

INFO: Connecting to the Plex with username “XXX”
[10:15:35] WARNING [PlexSync.PlexPlayer.connect:213] Failed to connect: (401) unauthorized; https://plex.tv/users/sign_in.xml <?xml version="1.0" encoding="UTF-8"?> You appear to be having trouble signing in to an account. You may wish to try resetting your password at https://plex.tv/reset
[10:15:36] WARNING [PlexSync.PlexPlayer.connect:213] Failed to connect: (401) unauthorized; https://plex.tv/users/sign_in.xml <?xml version="1.0" encoding="UTF-8"?> You appear to be having trouble signing in to an account. You may wish to try resetting your password at https://plex.tv/reset
[10:15:38] WARNING [PlexSync.PlexPlayer.connect:213] Failed to connect: (401) unauthorized; https://plex.tv/users/sign_in.xml <?xml version="1.0" encoding="UTF-8"?> You appear to be having trouble signing in to an account. You may wish to try resetting your password at https://plex.tv/reset
[10:15:38] ERROR [PlexSync.PlexPlayer.connect:216] Exiting after 3 failed attempts …

where the username it tries to use was actually what I put as the server name. Do you have any suggestions on how I might fix this?

Opening the options table gives me a blank screen

I am running this on a Windows 10 machine.

I go to file>options, and I just get a blank screen.

But if I exit out of "options", and then click on it again, I get an error message:

`See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.Data.SQLite.SQLiteException (0x80004005): SQL logic error or missing database
no such table: accounts
at System.Data.SQLite.SQLite3.Prepare(SQLiteConnection cnn, String strSql, SQLiteStatement previous, UInt32 timeoutMS, String& strRemain)
at System.Data.SQLite.SQLiteCommand.BuildNextCommand()
at System.Data.SQLite.SQLiteDataReader.NextResult()
at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave)
at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior)
at DS.PlexRatingsSync.PlexDatabaseControlller.ReadPlexAndMap[T](String sql) in C:\Users\vnormand\Documents\PlexRatingsSync\Solution\PlexRatingsSync\Classes\PlexDatabaseControlller.cs:line 67
at DS.PlexRatingsSync.Options.GetPreferences() in C:\Users\vnormand\Documents\PlexRatingsSync\Solution\PlexRatingsSync\Forms\Options.cs:line 44
at System.Windows.Forms.Form.OnLoad(EventArgs e)
at System.Windows.Forms.Form.OnCreateControl()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.WmShowWindow(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Form.WmShowWindow(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

************** Loaded Assemblies **************
mscorlib
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4420.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/mscorlib.dll

DS.PlexRatingsSync
Assembly Version: 2019.6.3.1
Win32 Version: 2019.6.3.1
CodeBase: file:///C:/Users/Ryan/Downloads/PlexRatingSync/DS.PlexRatingsSync.exe

System.Windows.Forms
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4400.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll

System
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4360.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll

System.Drawing
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4390.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll

DS.Library.MessageHandling
Assembly Version: 1.0.1.0
Win32 Version: 1.0.1.0
CodeBase: file:///C:/Users/Ryan/Downloads/PlexRatingSync/DS.Library.MessageHandling.DLL

log4net
Assembly Version: 2.0.8.0
Win32 Version: 2.0.8.0
CodeBase: file:///C:/Users/Ryan/Downloads/PlexRatingSync/log4net.DLL

System.Core
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4390.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll

System.Configuration
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4190.0 built by: NET48REL1LAST_B
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll

System.Xml
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4084.0 built by: NET48REL1
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll

DS.Controls.PropertyGridEx
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:///C:/Users/Ryan/Downloads/PlexRatingSync/DS.Controls.PropertyGridEx.DLL

System.Design
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4084.0 built by: NET48REL1
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Design/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Design.dll

System.Data.SQLite
Assembly Version: 1.0.104.0
Win32 Version: 1.0.104.0
CodeBase: file:///C:/Users/Ryan/Downloads/PlexRatingSync/System.Data.SQLite.DLL

System.Data
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4270.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_64/System.Data/v4.0_4.0.0.0__b77a5c561934e089/System.Data.dll

System.Transactions
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4084.0 built by: NET48REL1
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_64/System.Transactions/v4.0_4.0.0.0__b77a5c561934e089/System.Transactions.dll

System.EnterpriseServices
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4084.0 built by: NET48REL1
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_64/System.EnterpriseServices/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.EnterpriseServices.dll

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.`

Rating mismatches

Hi,

I thought I'd try this script out against a Test collection, just one album on the PLEX side and see what happened.

I started by:
Cleaning all the Ratings from the folder in PLEX
Cleaning all the Ratings on the folder in MM.
Setting one file to 5stars in MM
Syncing the tags between MM and the files.

Then ran the script.

It did match up the 5star test file I'd set, but it also set some other MP3s in PLEX to 2star and 3star, which aren't set in MM.

Whats the threshold it uses to commit to the update ?
When I look at the debug log for one of the wrong files:

Line 851: [16:38:59] DEBUG: Found match with score 35.0 for Dido - No Angel - Hunter: Adam Carroll - Lookin' Out the Screen Door - Hunter's Song
Line 5487: [16:41:50] DEBUG: Updating rating of track "Adam Carroll - Lookin' Out the Screen Door - Hunter's Song" to 3.0 stars

So I think its matching Dido there to Adam Carroll?

I'll look through the code next to see if I can spot a threshold value variable

ERROR: No matching distribution found for pywin32>=223 (from pypiwin32->-r requirements.txt (line 3))

Using Fedora 31.

[11:39:39] rolle plex-music-rating-sync $ sudo pip3.6 install -r requirements.txt
Collecting PlexAPI>=3.0.6
  Downloading PlexAPI-3.6.0.tar.gz (87 kB)
     |████████████████████████████████| 87 kB 1.1 MB/s 
Collecting fuzzywuzzy
  Using cached fuzzywuzzy-0.18.0-py2.py3-none-any.whl (18 kB)
Collecting pypiwin32
  Using cached pypiwin32-223-py3-none-any.whl (1.7 kB)
Collecting numpy
  Downloading numpy-1.18.4-cp36-cp36m-manylinux1_x86_64.whl (20.2 MB)
     |████████████████████████████████| 20.2 MB 18.5 MB/s 
Collecting requests
  Downloading requests-2.23.0-py2.py3-none-any.whl (58 kB)
     |████████████████████████████████| 58 kB 1.6 MB/s 
ERROR: Could not find a version that satisfies the requirement pywin32>=223 (from pypiwin32->-r requirements.txt (line 3)) (from versions: none)
ERROR: No matching distribution found for pywin32>=223 (from pypiwin32->-r requirements.txt (line 3))

Sync rating with server

Hi, thanks for the project. Helped me get started with coding an iTunes. xml library -> plex syncer. Noticed you had a comment on current issues How to change the ratings on the server (API endpoint).

In order to set rating on the server side you need to use the edit function and pass a dict of values to change.

e.g.

def updateTrack( artist, track, rating ):
    music = plex.library.section('Music')
    foundArtist = music.searchArtists(**{'title': artist})[0]
    foundTrack = foundArtist.track(track)
    print("Rating before: ", foundTrack._data.attrib.get('userRating'))
    foundTrack.edit(**{'userRating.value': rating})
    print("Rating after: ", foundTrack._data.attrib['userRating'])

updateTrack('30 Seconds To Mars', 'A Beautiful Lie', 6)

Please help

Complete newb here:
I managed to install git, python, pip,....etc and I tried running the program but I'm getting the following error :

"Traceback (most recent call last):
File "D:\Downloads\Applications\plex-music-rating-sync\sync_ratings.py", line 8, in
from sync_pair import *
File "D:\Downloads\Applications\plex-music-rating-sync\sync_pair.py", line 3, in
from fuzzywuzzy import fuzz
ModuleNotFoundError: No module named 'fuzzywuzzy'"

ERROR [PlexSync.PlexPlayer.connect:297] Error: Unable to connect

I think I've got it all setup right but I'm getting this error when using the api token or when using the password.

I get a different message if the password is wrong so I assume it's connecting somewhat.

Seperate question does this get ratings from voribis comments in flac files? I see you only mention ID3 which is used in MP3's.

Pre built version?

I don't suppose there's any chance you could release a pre-built install and run version of this? I wasn't really wanting to learn all about Python just to sync my ratings. I tried installing python and running pip3.8 install -r requirements.txt, but I get a ton of errors.

Error: Unable to Connect

I think this is mostly me being dense. I've installed all of the python modules but when running the command I get "Error: Unable to connect." The other odd thing though is that it isn't connecting with the username I specified per the message below. PMS is installed on a remote Linux box - do I need to be running this on the server with PMS installed? I wasn't sure if "Server" meant the name of the server hosting PMS or the name of the PMS instance itself (I tried both).

sync_ratings.py --server Plex-DB --player MediaMonkey --username trentflix --passwd PASSWORD

[19:40:34] INFO: Connecting to local player MediaMonkey
[19:40:34] INFO: Connecting to the Plex with username "Plex-DB"
[19:40:36] INFO: Connecting to remote player PlexPlayer on the server Plex
[19:40:36] ERROR [PlexSync.PlexPlayer.connect:225] Error: Unable to connect

I love the idea of this project though. I use Musicbee but luckily MediaMonkey auto-imports all of the song-ratings from the files themselves.

No scripting interface to MediaMonkey

Hi trying to get this to work with my library, does MediaMonkey need to be configured at all? I moved the installation of MediaMonkey back to my V: drive where the github repo is but not sure if this makes a difference. Can you assist?

|image

Media Monkey 5.0.0.2338? SongsDB5.SDBApplication

Hello,

Thank you for this great software, I'm sure this is user error on my part, but I keep getting this error with Media Monkey 5.0.0.2338

[PlexSync.MediaMonkey.connect:135] No scripting interface to MediaMonkey can be found. Exiting...

I don't see anything special in the instructions pertaining to MediaMonkey setup requirements, but I did see this link:
https://www.mediamonkey.com/wiki/Controlling_MM5_from_External_Applications

The SDBApplication class is largely unchanged from MediaMonkey 4, but the biggest difference is that it is named SongsDB5.SDBApplication instead of SongsDB.SDBApplication.

I notice the MediaPlayer.py, line 132, references the "SongsDB.SDBApplication" class (?), but simply editing it to "SongsDB5.SDBApplication" just threw different errors. This is all probably a red-herring covering up something obvious I'm missing, but I thought I'd drop it here in case.

Plex "forgetting" title entries - no error handling

Unfortunately with the latest release of plex they introduced an error where Plex just forgets the title of a track. The scipt stumbles over this with the following error (where **** are the missing titles, there are no **** showing, just a "- '"

[03:36:19] ERROR [PlexSync.TrackPair.match:103] Failed to search tracks for track 'Artist - Album - ******* ' stored at \elysium\Music\Plex\Alben\Artist\Album\Artist - Album - track - Title.mp3.

Unfortunately Plex is not known to fix their stuff fast. Is there a quickfix (TRY:) that I can implement myself to handle errors like this. With big libraries the script never runs through. You can refresh metadata on every album but Plex forgets just other titles. Really annoying.

More Info: https://www.reddit.com/r/PleX/comments/mp9m7w/music_song_titles_disappearing/

Direct rating from id3 tags?

Specifically is it possible to read them from Windows Media Player encoded ratings and load them into plex?

I.e. give a folder and then have it read recursively all media tracks and get the rating from there?

MediaMonkey to Plex on NAS

Hello, can I run this on my PC where Mediamonkey resides and output to Plex on my Nas on the network?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.