Git Product home page Git Product logo

Comments (31)

ZeroQI avatar ZeroQI commented on September 26, 2024

Please give me an impacted serie title and hama part of logs with tags listed.
Thetvdb doesn't support adult series so would not take tags (nor poster or ep sumaries) from there.

from hama.bundle.

currowth avatar currowth commented on September 26, 2024

I think all hentai is impacted. I.e Mezo Forte shows Future, Action, Martial Arts, Detective, Comedy, Pornography, and mecha but anidb has more tags. Can you make it merge all tags, or force it to get tags or metadata from anidb?

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

@currowth If you want more Genres, you can look at lowing the required weight.

image

Also note we have a pre-listed usable Genres. Only these will get added into Plex.

@ZeroQI is there a reason we have this pre-approved list? Its only used in AniDB. Both TVDB & TMDB genres are taken as is.

  ### Audience categories - all useful but not used often ############################################################################################################
  'Josei', 'Kodomo', 'Mina', 'Seinen', 'Shoujo', 'Shounen',
  ### Elements - many useful #########################################################################################################################################
  'Action', 'Martial Arts', 'Swordplay', 'Adventure', 'Angst', 'Anthropomorphism', 'Comedy', 'Parody', 'Slapstick', 'Super Deformed', 'Detective', 'Ecchi', 'Fantasy',
  'Contemporary Fantasy', 'Dark Fantasy', 'Ghost', 'High Fantasy', 'Magic', 'Vampire', 'Zombie', 'Harem', 'Reverse Harem', 'Henshin', 'Horror', 'Incest',
  'Mahou Shoujo', 'Pornography', 'Yaoi', 'Yuri', 'Romance', 'Love Polygon', 'Shoujo Ai', 'Shounen Ai', 'Sci-Fi', 'Alien', 'Mecha', 'Space Travel', 'Time Travel',
  'Thriller', 'Western',
  ### Fetishes. Leaving out most porn genres #########################################################################################################################
  'Futanari', 'Lolicon', 'Shotacon', 'Tentacle', 'Trap', 'Reverse Trap',
  ### Original Work - mainly useful ##################################################################################################################################
  'Game', 'Action Game', 'Dating Sim - Visual Novel', 'Erotic Game', 'RPG', 'Manga', '4-koma', 'Movie', 'Novel',
  ### Setting - most of the places aren't genres, some Time stuff is useful ##########################################################################################
  'Fantasy World', 'Parallel Universe', 'Virtual Reality', 'Hell', 'Space', 'Mars', 'Space Colony', 'Shipboard', 'Alternative Universe', 'Past', 'Present', 'Future',
  'Historical', '1920s', 'Bakumatsu - Meiji Period', 'Edo Period', 'Heian Period', 'Sengoku Period', 'Victorian Period', 'World War I', 'World War II', 'Alternative Present',
  ### Themes - many useful ###########################################################################################################################################
  'Anti-War', 'Art', 'Music', 'Band', 'Idol', 'Photography', 'Christmas', 'Coming of Age', 'Conspiracy', 'Cooking', 'Cosplay', 'Cyberpunk', 'Daily Life', 'Earthquake',
  'Post-War', 'Post-apocalypse', 'War', 'Dystopia', 'Friendship', 'Law and Order', 'Cops', 'Special Squads', 'Military', 'Airforce', 'Feudal Warfare', 'Navy',
  'Politics', 'Proxy Battles', 'Racism', 'Religion', 'School Life', 'All-boys School', 'All-girls School', 'Art School', 'Clubs', 'College', 'Delinquents',
  'Elementary School', 'High School', 'School Dormitory', 'Student Council', 'Transfer Student', 'Sports', 'Acrobatics', 'Archery', 'Badminton', 'Baseball',
  'Basketball', 'Board Games', 'Chess', 'Go', 'Mahjong', 'Shougi', 'Combat', 'Boxing', 'Judo', 'Kendo', 'Muay Thai', 'Wrestling', 'Cycling', 'Dodgeball', 'Fishing',
  'Football', 'Golf', 'Gymnastics', 'Horse Riding', 'Ice Skating', 'Inline Skating', 'Motorsport', 'Formula Racing', 'Street Racing', 'Rugby', 'Swimming', 'Tennis',
  'Track and Field', 'Volleyball', 'Steampunk', 'Summer Festival', 'Tragedy', 'Underworld', 'Assassin', 'Bounty Hunter', 'Mafia', 'Yakuza', 'Pirate', 'Terrorist',
  'Thief']

from hama.bundle.

currowth avatar currowth commented on September 26, 2024

Thanks for the info. I'm going to modify my file to include them.

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

@ZeroQI Actually looks like "MinimumWeight" pref is not even used anymore in the code. Looks like we should reinstate the "MinimumWeight" pref usage and allow any genre in AniDB as long as it meets the min weight.

I get the feeling you did the reverse to get where we are now.

from hama.bundle.

ZeroQI avatar ZeroQI commented on September 26, 2024

Sorry didn't get last sentence.

I didn't remove minimum weight volontarilly.
The list is inherited from original hama code. Always wondered about that. I think he did it to remove duplicate tags but that seem convoluted

I agree 100%. No clue when it dissapeared but code was there long time ago

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

Will get the pref reinstated and remove the pre-approved genres.

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

@ZeroQI please review
https://gist.github.com/EndOfLine369/8ee08c812a5f3943e6cc/revisions

2016-07-12 00:35:06,226 (-bbf1470) : DEBUG (init:621) - AniDB Genres (Weight): [('Ecchi', 600), ('Nudity', 500), ('Fantasy', 500), ('Action', 500), ('Swordplay', 400), ('Shoujo Ai', 400), ('Large Breasts', 300)]*

EX: (before code update & after w/min weight 400)
image

EX: (min weight 500)
image

EX: (min weight 100)
image

from hama.bundle.

ZeroQI avatar ZeroQI commented on September 26, 2024

@EndOfLine369 Nice! i would include the validity test in ValidatePrefs() to remove complexity there (limiting the tabultation space needed),
I know i didn't had it in the code before but lowering the tag makes sense but anidb probably have lower genre tags, and putting maybe on single line if not too long to math the single line above:
if this_tag.lower() in (restricted_genre.lower() for restricted_genre in RESTRICTED_GENRE_NAMES): metadata.content_rating = RESTRICTED_CONTENT_RATING

Yep perfect. Thanks for correcting and spotting. now have more time since wedding finished, if you need to look into something specific EndOfLine369..

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

Actually, instead of validating. Fix the "DefaultPrefs.json".
https://gist.github.com/EndOfLine369/8ee08c812a5f3943e6cc/revisions (last revision)
https://gist.github.com/EndOfLine369/329a66439a5e20248c3bf8d0a46ce4bc/revisions (last revision)

image

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

We should probably add in more possible entries for "RESTRICTED_GENRE_NAMES"
["18 Restricted", "Pornography", "Tv Censoring", "Borderline Porn", "Nudity", "Sex"]
https://en.wikipedia.org/wiki/Television_content_rating_systems#United_States

from hama.bundle.

ZeroQI avatar ZeroQI commented on September 26, 2024

Didn't though about that enum declaration, geniusly simple, and no more tests, thanks

For the ratings, actually great idea, a dict would be appropriate, all tags lowercase to ease the tests:
[https://en.wikipedia.org/wiki/Motion_picture_rating_system]

From

RESTRICTED_CONTENT_RATING    = "NC-17"
RESTRICTED_GENRE_NAMES       = [ '18 Restricted', 'Pornography' ]
@          if this_tag in (restricted_genre.lower() for restricted_genre in RESTRICTED_GENRE_NAMES):
            metadata.content_rating = RESTRICTED_CONTENT_RATING

To

RESTRICTED_CONTENT_US = {
"NC-17": [ '18 restricted', 'pornography', 'plot with porn', 'everybody has sex', 'sex toys' ],
"R":         [ 'tv censoring', 'borderline porn', 'sex'],
"NC-13": [ "ecchi"],
"PG":       [ "nudity", "large breasts", boobs in your face', 'magnetic boobs'],
}
         for content_rating in RESTRICTED_CONTENT_US:
            if this_tag in RESTRICTED_CONTENT_US[content_rating]:  metadata.content_rating = content_rating; break
          else: metadata.content_rating = "G"

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

I disagree on your ratings. this is also off topic of this ticket. will open up another ticket later and will show you what I have in mind to get these content ratings better sorted. I know I started the tangent 😉.

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

Will get the changes committed for the genre updates

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

Done

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

@currowth Thanks for bringing this to our attention.

from hama.bundle.

 avatar commented on September 26, 2024

I am now getting an error with this update:

2016-07-13 12:09:08,568 (808791400) :  CRITICAL (agentkit:1067) - Exception in the update function of agent named 'HamaTV', called with guid 'com.plexapp.agents.hama://anidb-4252?lang=en' (most recent call last):
  File "/usr/local/share/plexmediaserver-plexpass/Resources/Plug-ins-a17e99e/Framework.bundle/Contents/Resources/Versions/2/Python/Framework/api/agentkit.py", line 1065, in _update
    agent.update(obj, media, lang, **kwargs)
  File "/usr/local/plexdata-plexpass/Plex Media Server/Plug-ins/Hama.bundle/Contents/Code/__init__.py", line 848, in update
    def update(self, metadata, media, lang, force ): self.Update(metadata, media, lang, force,  False )
  File "/usr/local/plexdata-plexpass/Plex Media Server/Plug-ins/Hama.bundle/Contents/Code/__init__.py", line 618, in Update
    elif not movie and (len(media.seasons)>2 or max(map(int, media.seasons.keys()))>1):  keys = ["tvdbid: %s"  % (WEB_LINK % (TVDB_SERIE_URL  % tvdbid,  tvdbid) )]
TypeError: int() argument must be a string or a number, not 'NoneType'

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

@lazeraman That part of the code was not touched in this ticket's updates. As from what you posted it is not possible to error out on that line as "media.seasons.keys()" will only ever be ints so it must be erroring out somewhere else and throwing a bad line num which python does do sometimes.

The only piece that was updated with an int case was for the weight preference. So with that in mind, I suspect you did not update your "DefaultPrefs.json". Please update the file, make sure your agent gets reloaded, confirm your weight setting then try again.

image

And just to confirm, that was from the 'com.plexapp.agents.hama.log' log? I get the feeling it might not.

from hama.bundle.

 avatar commented on September 26, 2024

@EndOfLine369 It came from com.plexapp.agents.hama.log.1. I also reverted to the previous revision to see if like you said was due to the previous revision that added the code. It seems to be only happening with the current revision as it works normally with the previous one.

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

Please provide your full hama log for the run that errors out.

from hama.bundle.

 avatar commented on September 26, 2024
2016-07-13 16:21:38,115 (802406400) :  INFO (core:349) - Starting framework core - Version: 2.6.3, Build: a17e99e (Thu Jun 23 19:19:47 UTC 2016)
2016-07-13 16:21:38,115 (802406400) :  DEBUG (core:361) - Using the standard policy
2016-07-13 16:21:38,115 (802406400) :  DEBUG (core:450) - Starting runtime component.
2016-07-13 16:21:38,117 (802406400) :  DEBUG (core:450) - Starting caching component.
2016-07-13 16:21:38,117 (802406400) :  DEBUG (core:450) - Starting data component.
2016-07-13 16:21:38,117 (802406400) :  DEBUG (core:450) - Starting networking component.
2016-07-13 16:21:38,118 (802406400) :  DEBUG (networking:282) - Loaded HTTP cookies
2016-07-13 16:21:38,118 (802406400) :  DEBUG (networking:450) - Setting the default network timeout to 20.0
2016-07-13 16:21:38,119 (802406400) :  DEBUG (core:450) - Starting localization component.
2016-07-13 16:21:38,119 (802406400) :  INFO (localization:409) - Setting the default locale to en-us
2016-07-13 16:21:38,119 (802406400) :  DEBUG (core:450) - Starting messaging component.
2016-07-13 16:21:38,119 (802406400) :  DEBUG (core:450) - Starting debugging component.
2016-07-13 16:21:38,120 (802406400) :  DEBUG (core:450) - Starting services component.
2016-07-13 16:21:38,120 (802406400) :  DEBUG (core:450) - Starting myplex component.
2016-07-13 16:21:38,120 (808653c00) :  DEBUG (networking:166) - Requesting 'http://127.0.0.1:32400/system/messaging/clear_events/com.plexapp.agents.hama'
2016-07-13 16:21:38,120 (802406400) :  DEBUG (core:450) - Starting notifications component.
2016-07-13 16:21:38,261 (802406400) :  DEBUG (accessor:68) - Creating a new model access point for provider com.plexapp.agents.hama in namespace 'metadata'
2016-07-13 16:21:38,266 (802406400) :  DEBUG (networking:166) - Requesting 'http://127.0.0.1:32400/:/plugins/com.plexapp.system/resourceHashes'
2016-07-13 16:21:38,283 (808792400) :  DEBUG (services:265) - Plug-in is not daemonized - loading services from system
2016-07-13 16:21:38,283 (802406400) :  DEBUG (runtime:1117) - Created a thread named 'load_all_services'
2016-07-13 16:21:38,284 (808792400) :  DEBUG (networking:166) - Requesting 'http://127.0.0.1:32400/:/plugins/com.plexapp.system/messaging/function/X0J1bmRsZVNlcnZpY2U6QWxsU2VydmljZXM_/Y2VyZWFsMQoxCmxpc3QKMApyMAo_/Y2VyZWFsMQoxCmRpY3QKMApyMAo_'
2016-07-13 16:21:38,284 (802406400) :  DEBUG (runtime:1117) - Created a thread named 'get_server_info'
2016-07-13 16:21:38,285 (802406400) :  DEBUG (core:150) - Finished starting framework core
2016-07-13 16:21:38,285 (802406400) :  DEBUG (core:560) - Loading plug-in code
2016-07-13 16:21:38,285 (8085ee000) :  DEBUG (networking:166) - Requesting 'http://127.0.0.1:32400'
2016-07-13 16:21:39,102 (802406400) :  DEBUG (core:566) - Finished loading plug-in code
2016-07-13 16:21:39,191 (808792400) :  DEBUG (services:362) - Loaded services
2016-07-13 16:21:39,192 (8085ee000) :  DEBUG (core:538) - Machine identifier is 49673621a5c5c44cb2700a7454ccee0ccd437768
2016-07-13 16:21:39,194 (8085ee000) :  DEBUG (core:539) - Server version is 1.0.0.2261-a17e99e
2016-07-13 16:21:39,196 (8085edc00) :  DEBUG (services:438) - No shared code to load
2016-07-13 16:21:39,197 (802406400) :  DEBUG (preferences:258) - Loaded preferences from DefaultPrefs.json
2016-07-13 16:21:39,198 (802406400) :  DEBUG (preferences:178) - Loaded the user preferences for com.plexapp.agents.hama
2016-07-13 16:21:39,198 (802406400) :  DEBUG (agentkit:1104) - Creating new agent class called HamaTVAgent
2016-07-13 16:21:39,199 (802406400) :  DEBUG (agentkit:922) - Updating agent information: [{'media_types': ['TV_Show'], 'accepts_from': ['com.plexapp.agents.localmedia'], 'fallback_agent': False, 'contributes_to': None, 'languages': ['en'], 'persist_stored_files': True, 'version': 0, 'primary_provider': True, 'prefs': True, 'name': 'HamaTV'}]
2016-07-13 16:21:39,199 (802406400) :  DEBUG (networking:166) - Requesting 'http://127.0.0.1:32400/:/plugins/com.plexapp.system/messaging/function/X0FnZW50U2VydmljZTpVcGRhdGVJbmZv/Y2VyZWFsMQoxCmxpc3QKMApyMAo_/Y2VyZWFsMQo2CmRpY3QKbGlzdApkaWN0Cmxpc3QKbGlzdApsaXN0CjIKczIzCmNvbS5wbGV4YXBwLmFnZW50cy5oYW1hczEwCmlkZW50aWZpZXJyMQpzMTAKYWdlbnRfaW5mbzEKcjIKMTAKcjMKczExCm1lZGlhX3R5cGVzcjQKczEyCmFjY2VwdHNfZnJvbWIwczE0CmZhbGxiYWNrX2FnZW50bnMxNApjb250cmlidXRlc190b3I1CnM5Cmxhbmd1YWdlc2IxczIwCnBlcnNpc3Rfc3RvcmVkX2ZpbGVzaTAKczcKdmVyc2lvbmIxczE2CnByaW1hcnlfcHJvdmlkZXJiMXM1CnByZWZzczYKSGFtYVRWczQKbmFtZTEKczcKVFZfU2hvdzEKczI5CmNvbS5wbGV4YXBwLmFnZW50cy5sb2NhbG1lZGlhMQpzMgplbnIwCg__'
2016-07-13 16:21:39,208 (802406400) :  DEBUG (agentkit:1104) - Creating new agent class called HamaMovieAgent
2016-07-13 16:21:39,208 (802406400) :  DEBUG (agentkit:922) - Updating agent information: [{'media_types': ['TV_Show'], 'accepts_from': ['com.plexapp.agents.localmedia'], 'fallback_agent': False, 'contributes_to': None, 'languages': ['en'], 'persist_stored_files': True, 'version': 0, 'primary_provider': True, 'prefs': True, 'name': 'HamaTV'}, {'media_types': ['Movie'], 'accepts_from': ['com.plexapp.agents.localmedia'], 'fallback_agent': False, 'contributes_to': None, 'languages': ['en'], 'persist_stored_files': True, 'version': 0, 'primary_provider': True, 'prefs': True, 'name': 'HamaMovies'}]
2016-07-13 16:21:39,209 (802406400) :  DEBUG (networking:166) - Requesting 'http://127.0.0.1:32400/:/plugins/com.plexapp.system/messaging/function/X0FnZW50U2VydmljZTpVcGRhdGVJbmZv/Y2VyZWFsMQoxCmxpc3QKMApyMAo_/Y2VyZWFsMQoxMApkaWN0Cmxpc3QKZGljdApsaXN0Cmxpc3QKbGlzdApkaWN0Cmxpc3QKbGlzdApsaXN0CjIKczIzCmNvbS5wbGV4YXBwLmFnZW50cy5oYW1hczEwCmlkZW50aWZpZXJyMQpzMTAKYWdlbnRfaW5mbzIKcjIKcjYKMTAKcjMKczExCm1lZGlhX3R5cGVzcjQKczEyCmFjY2VwdHNfZnJvbWIwczE0CmZhbGxiYWNrX2FnZW50bnMxNApjb250cmlidXRlc190b3I1CnM5Cmxhbmd1YWdlc2IxczIwCnBlcnNpc3Rfc3RvcmVkX2ZpbGVzaTAKczcKdmVyc2lvbmIxczE2CnByaW1hcnlfcHJvdmlkZXJiMXM1CnByZWZzczYKSGFtYVRWczQKbmFtZTEKczcKVFZfU2hvdzEKczI5CmNvbS5wbGV4YXBwLmFnZW50cy5sb2NhbG1lZGlhMQpzMgplbjEwCnI3CnMxMQptZWRpYV90eXBlc3I4CnMxMgphY2NlcHRzX2Zyb21iMHMxNApmYWxsYmFja19hZ2VudG5zMTQKY29udHJpYnV0ZXNfdG9yOQpzOQpsYW5ndWFnZXNiMXMyMApwZXJzaXN0X3N0b3JlZF9maWxlc2kwCnM3CnZlcnNpb25iMXMxNgpwcmltYXJ5X3Byb3ZpZGVyYjFzNQpwcmVmc3MxMApIYW1hTW92aWVzczQKbmFtZTEKczUKTW92aWUxCnMyOQpjb20ucGxleGFwcC5hZ2VudHMubG9jYWxtZWRpYTEKczIKZW5yMAo_'
2016-07-13 16:21:39,218 (802406400) :  INFO (__init__:48) - DefaultPrefs.json is valid
2016-07-13 16:21:39,218 (802406400) :  DEBUG (__init__:66) - ### HTTP Anidb Metadata Agent (HAMA) Started ##############################################################################################################
2016-07-13 16:21:39,219 (802406400) :  DEBUG (__init__:795) - xmlElementFromFile() - url: 'http://anidb.net/api/anime-titles.xml.gz', filename: 'anime-titles.xml'
2016-07-13 16:21:43,229 (802406400) :  DEBUG (networking:161) - Fetching 'http://anidb.net/api/anime-titles.xml.gz' from the HTTP cache
2016-07-13 16:21:43,421 (802406400) :  DEBUG (__init__:795) - xmlElementFromFile() - url: 'http://rawgithub.com/ScudLee/anime-lists/master/anime-list-master.xml', filename: 'anime-list-master.xml'
2016-07-13 16:21:43,423 (802406400) :  DEBUG (networking:161) - Fetching 'http://rawgithub.com/ScudLee/anime-lists/master/anime-list-master.xml' from the HTTP cache
2016-07-13 16:21:43,496 (802406400) :  DEBUG (__init__:795) - xmlElementFromFile() - url: 'http://rawgithub.com/ScudLee/anime-lists/master/anime-movieset-list.xml', filename: 'anime-movieset-list.xml'
2016-07-13 16:21:43,498 (802406400) :  DEBUG (networking:161) - Fetching 'http://rawgithub.com/ScudLee/anime-lists/master/anime-movieset-list.xml' from the HTTP cache
2016-07-13 16:21:43,504 (802406400) :  INFO (core:611) - Started plug-in
2016-07-13 16:21:43,505 (802406400) :  DEBUG (socketinterface:160) - Starting socket server
2016-07-13 16:21:43,505 (802406400) :  DEBUG (runtime:1117) - Created a thread named 'start'
2016-07-13 16:21:43,506 (802406400) :  INFO (socketinterface:184) - Socket server started on port 39110
2016-07-13 16:21:43,506 (802406400) :  INFO (pipeinterface:25) - Entering run loop
2016-07-13 16:21:43,506 (802406400) :  DEBUG (runtime:717) - Handling request GET /:/prefixes
2016-07-13 16:21:43,507 (802406400) :  DEBUG (runtime:814) - Found route matching /:/prefixes
2016-07-13 16:21:43,508 (802406400) :  DEBUG (runtime:924) - Response: [200] MediaContainer, 148 bytes
2016-07-13 16:21:43,518 (80b04c400) :  DEBUG (runtime:717) - Handling request GET /:/plugins/com.plexapp.agents.hama/messaging/function/X0FnZW50S2l0OlVwZGF0ZU1ldGFkYXRh/Y2VyZWFsMQoxCmxpc3QKMApyMAo_/Y2VyZWFsMQoxCmRpY3QKMTAKczIKZW5zNApsYW5nYjFzNQpmb3JjZWIwczgKcGVyaW9kaWNzNAo1NDE4czQKZGJpZGkwCnM3CnZlcnNpb25uczEwCnBhcmVudEdVSURuczgKcGFyZW50SURzNwpUVl9TaG93czEwCm1lZGlhX3R5cGVzNDQKY29tLnBsZXhhcHAuYWdlbnRzLmhhbWE6Ly9hbmlkYi00MjUyP2xhbmc9ZW5zNApndWlkczEwCmFuaWRiLTQyNTJzMgppZHIwCg__
2016-07-13 16:21:43,532 (80b04c400) :  DEBUG (runtime:814) - Found route matching /:/plugins/com.plexapp.agents.hama/messaging/function/X0FnZW50S2l0OlVwZGF0ZU1ldGFkYXRh/Y2VyZWFsMQoxCmxpc3QKMApyMAo_/Y2VyZWFsMQoxCmRpY3QKMTAKczIKZW5zNApsYW5nYjFzNQpmb3JjZWIwczgKcGVyaW9kaWNzNAo1NDE4czQKZGJpZGkwCnM3CnZlcnNpb25uczEwCnBhcmVudEdVSURuczgKcGFyZW50SURzNwpUVl9TaG93czEwCm1lZGlhX3R5cGVzNDQKY29tLnBsZXhhcHAuYWdlbnRzLmhhbWE6Ly9hbmlkYi00MjUyP2xhbmc9ZW5zNApndWlkczEwCmFuaWRiLTQyNTJzMgppZHIwCg__
2016-07-13 16:21:43,533 (80b04c400) :  DEBUG (model:32) - Loading model with GUID com.plexapp.agents.hama://anidb-4252?lang=en
2016-07-13 16:21:43,535 (80b04c400) :  DEBUG (model:234) - Deserializing from /usr/local/plexdata-plexpass/Plex Media Server/Metadata/TV Shows/1/68c94186cb77ef1bf5037a872e68d3ce9c03451.bundle/Contents/com.plexapp.agents.hama/Info.xml
2016-07-13 16:21:43,540 (80b04c400) :  DEBUG (networking:166) - Requesting 'http://127.0.0.1:32400/library/metadata/5418/tree'
2016-07-13 16:21:43,547 (80b04c400) :  DEBUG (__init__:495) - --- Update Begin -------------------------------------------------------------------------------------------
2016-07-13 16:21:43,547 (80b04c400) :  DEBUG (__init__:618) - Update - metadata source: 'anidb', id: '4252', Title: 'Consenting Adultery',([...], [...], True)
2016-07-13 16:21:43,566 (80b04c400) :  DEBUG (__init__:644) - anidbTvdbMapping() - anidb: '4252', tvbdid: 'hentai', tmdbid: '', imbdid: '', studio: '', defaulttvdbseason: '1', name: 'Mrs. Junkie'
2016-07-13 16:21:43,567 (80b04c400) :  DEBUG (__init__:495) - Update() - AniDB mode - AniDB Serie XML: http://api.anidb.net:9001/httpapi?request=anime&client=hama&clientver=1&protover=1&aid=4252, AniDB/4252.xml
2016-07-13 16:21:43,567 (80b04c400) :  DEBUG (__init__:795) - xmlElementFromFile() - url: 'http://api.anidb.net:9001/httpapi?request=anime&client=hama&clientver=1&protover=1&aid=4252', filename: 'AniDB/4252.xml'
2016-07-13 16:21:47,577 (80b04c400) :  DEBUG (networking:161) - Fetching 'http://api.anidb.net:9001/httpapi?request=anime&client=hama&clientver=1&protover=1&aid=4252' from the HTTP cache
2016-07-13 16:21:47,581 (80b04c400) :  DEBUG (__init__:618) - Update() - AniDB title: 'Consenting Adultery', original title: 'Mrs. Junkie', metadata.title 'Consenting Adultery'*
2016-07-13 16:21:47,582 (80b04c400) :  DEBUG (__init__:618) - Update() - AniDB Start Date: '2006-02-25'
2016-07-13 16:21:47,582 (80b04c400) :  DEBUG (__init__:618) - update() - AniDB Ratings:    '5.91'*
2016-07-13 16:21:47,584 (80b04c400) :  CRITICAL (agentkit:1067) - Exception in the update function of agent named 'HamaTV', called with guid 'com.plexapp.agents.hama://anidb-4252?lang=en' (most recent call last):
  File "/usr/local/share/plexmediaserver-plexpass/Resources/Plug-ins-a17e99e/Framework.bundle/Contents/Resources/Versions/2/Python/Framework/api/agentkit.py", line 1065, in _update
    agent.update(obj, media, lang, **kwargs)
  File "/usr/local/plexdata-plexpass/Plex Media Server/Plug-ins/Hama.bundle/Contents/Code/__init__.py", line 848, in update
    def update(self, metadata, media, lang, force ): self.Update(metadata, media, lang, force,  False )
  File "/usr/local/plexdata-plexpass/Plex Media Server/Plug-ins/Hama.bundle/Contents/Code/__init__.py", line 618, in Update
    elif not movie and (len(media.seasons)>2 or max(map(int, media.seasons.keys()))>1):  keys = ["tvdbid: %s"  % (WEB_LINK % (TVDB_SERIE_URL  % tvdbid,  tvdbid) )]
TypeError: int() argument must be a string or a number, not 'NoneType'

2016-07-13 16:21:47,590 (80b04c400) :  DEBUG (model:229) - Serializing to /usr/local/plexdata-plexpass/Plex Media Server/Metadata/TV Shows/1/68c94186cb77ef1bf5037a872e68d3ce9c03451.bundle/Contents/com.plexapp.agents.hama/Info.xml
2016-07-13 16:21:47,592 (80b04c400) :  DEBUG (runtime:88) - Sending packed state data (104 bytes)
2016-07-13 16:21:47,592 (80b04c400) :  DEBUG (runtime:924) - Response: [200] str, 16 bytes

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

Nice, makes it clear it is not the section it is providing the line for.
As code does:

  • AniDB Title (is seen)
  • AniDB Start Date (is seen)
  • AniDB Ratings (is seen)
  • AniDB Genres (NOT seen)

So is indeed something in this update......hmmmm.........

 -          if this_tag in (genre_name.lower() for genre_name in GENRE_NAMES):
 -            genres [ this_tag_caps ] = int(tag.get('weight')) # Remove genre whitelist
 +          if int(tag.get('weight')) >= int(Prefs['MinimumWeight']): genres [ this_tag_caps ] = int(tag.get('weight'))

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

This tells me it could only error out on either int(tag.get('weight')) or int(Prefs['MinimumWeight']).
Tags look fine in AniDB api and I am unable to replicate so the only thing that would differ from our setup is the Prefs['MinimumWeight']. Please show me a screenshot of your library edit showing the weight option your using.

2016-07-13 15:38:38,541 (-c18f470) :  DEBUG (__init__:618) - --- Update Begin -------------------------------------------------------------------------------------------
2016-07-13 15:38:38,542 (-c18f470) :  DEBUG (__init__:618) - Update - metadata source: 'anidb', id: '4252', Title: 'None',([...], [...], True)
2016-07-13 15:38:38,620 (-c18f470) :  DEBUG (__init__:644) - anidbTvdbMapping() - anidb: '4252', tvbdid: 'hentai', tmdbid: '', imbdid: '', studio: '', defaulttvdbseason: '1', name: 'Mrs. Junkie'
2016-07-13 15:38:38,625 (-c18f470) :  DEBUG (__init__:618) - Update() - AniDB mode - AniDB Serie XML: http://api.anidb.net:9001/httpapi?request=anime&client=hama&clientver=1&protover=1&aid=4252, AniDB/4252.xml
2016-07-13 15:38:38,625 (-c18f470) :  DEBUG (__init__:795) - xmlElementFromFile() - url: 'http://api.anidb.net:9001/httpapi?request=anime&client=hama&clientver=1&protover=1&aid=4252', filename: 'AniDB/4252.xml'
2016-07-13 15:38:42,643 (-c18f470) :  DEBUG (networking:166) - Requesting 'http://api.anidb.net:9001/httpapi?request=anime&client=hama&clientver=1&protover=1&aid=4252'
2016-07-13 15:38:42,902 (-c18f470) :  DEBUG (__init__:618) - Update() - AniDB title: 'Consenting Adultery', original title: 'Mrs. Junkie', metadata.title 'None'
2016-07-13 15:38:42,922 (-c18f470) :  DEBUG (__init__:618) - Update() - AniDB Start Date: '2006-02-25'
2016-07-13 15:38:42,923 (-c18f470) :  DEBUG (__init__:618) - update() - AniDB Ratings:    '5.91'
2016-07-13 15:38:42,952 (-c18f470) :  DEBUG (__init__:618) - Update() - genres: [('Nudity', 600), ('Large Breasts', 600), ('Asia', 600), ('Sex', 600), ('Plot Continuity', 600), ('Japan', 600), ('Earth', 600), ('Housewives', 600), ('Present', 600)] ['Nudity', 'Large Breasts', 'Asia', 'Sex', 'Plot Continuity', 'Japan', 'Earth', 'Housewives', 'Present']
2016-07-13 15:38:42,953 (-c18f470) :  DEBUG (__init__:618) - AniDB Genres (Weight): Nudity (600) Large Breasts (600) Asia (600) Sex (600) Plot Continuity (600) Japan (600) Earth (600) Housewives (600) Present (600) 
2016-07-13 15:38:42,959 (-c18f470) :  DEBUG (__init__:667) - anidbCollectionMapping() - anidbid is not part of any collection, related_anime_list: '[]'
2016-07-13 15:38:42,960 (-c18f470) :  DEBUG (__init__:618) - AniDB Creator data: Raika Ken is a director, T-Rex is a studio, Buruge On Demand is a writer, 
2016-07-13 15:38:42,963 (-c18f470) :  DEBUG (__init__:618) - Update() - AniDB Poster, url: 'http://img7.anidb.net/pics/anime/46061.jpg'
2016-07-13 15:38:42,989 (-c18f470) :  DEBUG (networking:166) - Requesting 'http://img7.anidb.net/pics/anime/46061.jpg'
2016-07-13 15:38:43,288 (-c18f470) :  DEBUG (networking:198) - Not caching 'http://img7.anidb.net/pics/anime/46061.jpg' (content type 'image/jpeg' not cacheable in Agent plug-ins)
2016-07-13 15:38:43,290 (-c18f470) :  DEBUG (__init__:785) - metadata_download() - url: 'http://img7.anidb.net/pics/anime/46061.jpg', num: '99', filename: 'AniDB/46061.jpg'
2016-07-13 15:38:43,292 (-c18f470) :  DEBUG (__init__:618) - Update() - AniDB episode title: 'Volume 1'
2016-07-13 15:38:43,294 (-c18f470) :  DEBUG (__init__:618) - Update() - AniDB AirDate '2006-02-25'
2016-07-13 15:38:43,296 (-c18f470) :  DEBUG (__init__:618) - Update() - AniDB duration: '1800000'
2016-07-13 15:38:43,298 (-c18f470) :  DEBUG (__init__:618) - Update() - DURATION: 1800000, numEpisodes: 1
2016-07-13 15:38:43,299 (-c18f470) :  DEBUG (__init__:618) - Locked 'anime-list anidbid missing' [True, 1468442323]
2016-07-13 15:38:43,351 (-c18f470) :  DEBUG (__init__:623) - Unlocked 'anime-list anidbid missing' [False, 0]
2016-07-13 15:38:43,351 (-c18f470) :  DEBUG (__init__:618) - Locked 'anime-list studio logos' [True, 1468442323]
2016-07-13 15:38:43,384 (-c18f470) :  DEBUG (__init__:623) - Unlocked 'anime-list studio logos' [False, 0]
2016-07-13 15:38:43,385 (-c18f470) :  DEBUG (__init__:618) - Locked 'AniDB summaries missing' [True, 1468442323]
2016-07-13 15:38:43,409 (-c18f470) :  DEBUG (__init__:623) - Unlocked 'AniDB summaries missing' [False, 0]
2016-07-13 15:38:43,410 (-c18f470) :  DEBUG (__init__:618) - Locked 'Plex themes missing' [True, 1468442323]
2016-07-13 15:38:43,441 (-c18f470) :  DEBUG (__init__:623) - Unlocked 'Plex themes missing' [False, 0]
2016-07-13 15:38:43,441 (-c18f470) :  DEBUG (__init__:618) - Locked 'TVDB posters missing' [True, 1468442323]
2016-07-13 15:38:43,450 (-c18f470) :  DEBUG (__init__:623) - Unlocked 'TVDB posters missing' [False, 0]
2016-07-13 15:38:43,451 (-c18f470) :  DEBUG (__init__:618) - Locked 'Missing Specials' [True, 1468442323]
2016-07-13 15:38:43,473 (-c18f470) :  DEBUG (__init__:623) - Unlocked 'Missing Specials' [False, 0]
2016-07-13 15:38:43,473 (-c18f470) :  DEBUG (__init__:618) - Locked 'Missing Episodes' [True, 1468442323]
2016-07-13 15:38:43,480 (-c18f470) :  DEBUG (__init__:623) - Unlocked 'Missing Episodes' [False, 0]
2016-07-13 15:38:43,480 (-c18f470) :  DEBUG (__init__:618) - Locked 'AniDB posters missing' [True, 1468442323]
2016-07-13 15:38:43,482 (-c18f470) :  DEBUG (__init__:623) - Unlocked 'AniDB posters missing' [False, 0]
2016-07-13 15:38:43,483 (-c18f470) :  DEBUG (__init__:618) - Locked 'anime-list tvdbid missing' [True, 1468442323]
2016-07-13 15:38:43,490 (-c18f470) :  DEBUG (__init__:623) - Unlocked 'anime-list tvdbid missing' [False, 0]
2016-07-13 15:38:43,491 (-c18f470) :  DEBUG (__init__:618) - Locked 'TVDB season posters missing' [True, 1468442323]
2016-07-13 15:38:43,509 (-c18f470) :  DEBUG (__init__:623) - Unlocked 'TVDB season posters missing' [False, 0]
2016-07-13 15:38:43,510 (-c18f470) :  DEBUG (__init__:618) - Locked 'Missing Special Summaries' [True, 1468442323]
2016-07-13 15:38:43,536 (-c18f470) :  DEBUG (__init__:623) - Unlocked 'Missing Special Summaries' [False, 0]
2016-07-13 15:38:43,537 (-c18f470) :  DEBUG (__init__:618) - Locked 'Missing Episode Summaries' [True, 1468442323]
2016-07-13 15:38:43,579 (-c18f470) :  DEBUG (__init__:623) - Unlocked 'Missing Episode Summaries' [False, 0]
2016-07-13 15:38:43,580 (-c18f470) :  DEBUG (__init__:624) - --- Update end -------------------------------------------------------------------------------------------------

from hama.bundle.

 avatar commented on September 26, 2024

min weight

I think this is what your looking for. I changed the weight and saved my preferences. I dropped it from 500 to 100 refreshed the meta and the tags loaded. I raised it back up to 500 and some of the tags disappeared. I assume that's how it was intended to work (thanks btw, that is awesome). I cannot replicate the error after having changed the preference.

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

I think it gets to the last possible thing I was thinking of. In that somehow the change in the "DefaultPrefs.json" requires an edit/save. Which you just did and now it is working. Other people might have this issue then. Something needs to go in I guess to catch when this save has not happened.

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

@ZeroQI, you can see that the pref validation passed in his log.
2016-07-13 16:21:39,218 (802406400) : INFO (__init__:48) - DefaultPrefs.json is valid
I suspect that we probably have to fix the validation def as Prefs['MinimumWeight'] == None it seems until preferences were saved.

FROM:
def ValidatePrefs(): #     a = sum(getattr(t, name, 0) for name in "xyz")
  DefaultPrefs = ("GetTvdbFanart", "GetTvdbPosters", "GetTvdbBanners", "GetAnidbPoster", "GetTmdbFanart", "GetTmdbPoster", "GetASSPosters", "localart", "adult", 
                  "GetPlexThemes", "MinimumWeight", "SerieLanguage1", "SerieLanguage2", "SerieLanguage3", "EpisodeLanguage1", "EpisodeLanguage2", "https")
  try:  [Prefs[key] for key in DefaultPrefs]
  except:  Log.Error("DefaultPrefs.json invalid" );  return MessageContainer ('Error', "Value '%s' missing from 'DefaultPrefs.json', update it" % key)
  else:    Log.Info ("DefaultPrefs.json is valid");  return MessageContainer ('Success', 'HAMA - Provided preference values are ok')

TO:
def ValidatePrefs(): #     a = sum(getattr(t, name, 0) for name in "xyz")
  DefaultPrefs = ("GetTvdbFanart", "GetTvdbPosters", "GetTvdbBanners", "GetAnidbPoster", "GetTmdbFanart", "GetTmdbPoster", "GetASSPosters", "localart", "adult", 
                  "GetPlexThemes", "MinimumWeight", "SerieLanguage1", "SerieLanguage2", "SerieLanguage3", "EpisodeLanguage1", "EpisodeLanguage2", "https")
  try:  
    for key in DefaultPrefs: Log.Info("Prefs[%s] = %s" % (key, Prefs[key]))
    if [Prefs[key] == None for key in DefaultPrefs].count(True) > 0: 
           err_str = "Some Pref values do not exist. Edit and save your preferences."; Log.Error(err_str);                                  return MessageContainer ('Error',   err_str)
  except:  err_str = "Value '%s' missing from 'DefaultPrefs.json', update it." % key;  Log.Error("DefaultPrefs.json invalid. " + err_str);  return MessageContainer ('Error',   err_str)
  else:    ok_str  = 'HAMA - Provided preference values are ok';                       Log.Info ("DefaultPrefs.json is valid." + ok_str );  return MessageContainer ('Success', ok_str )

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

Updated master to catch 'None' values and also print out the preference values into the log.

2016-07-14 02:49:52,094 (-8e45530) :  INFO (__init__:47) - Prefs[GetTvdbFanart] = True
2016-07-14 02:49:52,095 (-8e45530) :  INFO (__init__:47) - Prefs[GetTvdbPosters] = True
2016-07-14 02:49:52,096 (-8e45530) :  INFO (__init__:47) - Prefs[GetTvdbBanners] = True
2016-07-14 02:49:52,096 (-8e45530) :  INFO (__init__:47) - Prefs[GetAnidbPoster] = True
2016-07-14 02:49:52,097 (-8e45530) :  INFO (__init__:47) - Prefs[GetTmdbFanart] = False
2016-07-14 02:49:52,098 (-8e45530) :  INFO (__init__:47) - Prefs[GetTmdbPoster] = False
2016-07-14 02:49:52,098 (-8e45530) :  INFO (__init__:47) - Prefs[GetASSPosters] = True
2016-07-14 02:49:52,099 (-8e45530) :  INFO (__init__:47) - Prefs[localart] = True
2016-07-14 02:49:52,100 (-8e45530) :  INFO (__init__:47) - Prefs[adult] = True
2016-07-14 02:49:52,100 (-8e45530) :  INFO (__init__:47) - Prefs[GetPlexThemes] = False
2016-07-14 02:49:52,101 (-8e45530) :  INFO (__init__:47) - Prefs[MinimumWeight] = 400
2016-07-14 02:49:52,102 (-8e45530) :  INFO (__init__:47) - Prefs[SerieLanguage1] = en
2016-07-14 02:49:52,102 (-8e45530) :  INFO (__init__:47) - Prefs[SerieLanguage2] = main
2016-07-14 02:49:52,103 (-8e45530) :  INFO (__init__:47) - Prefs[SerieLanguage3] = x-jat
2016-07-14 02:49:52,104 (-8e45530) :  INFO (__init__:47) - Prefs[EpisodeLanguage1] = en
2016-07-14 02:49:52,104 (-8e45530) :  INFO (__init__:47) - Prefs[EpisodeLanguage2] = x-jat
2016-07-14 02:49:52,105 (-8e45530) :  INFO (__init__:47) - Prefs[https] = False
2016-07-14 02:49:52,109 (-8e45530) :  INFO (__init__:51) - DefaultPrefs.json is valid.HAMA - Provided preference values are ok
2016-07-14 02:43:01,761 (-8ea9530) :  INFO (__init__:47) - Prefs[GetTvdbFanart] = True
2016-07-14 02:43:01,762 (-8ea9530) :  INFO (__init__:47) - Prefs[GetTvdbPosters] = True
2016-07-14 02:43:01,763 (-8ea9530) :  INFO (__init__:47) - Prefs[GetTvdbBanners] = True
2016-07-14 02:43:01,763 (-8ea9530) :  INFO (__init__:47) - Prefs[GetAnidbPoster] = True
2016-07-14 02:43:01,764 (-8ea9530) :  INFO (__init__:47) - Prefs[GetTmdbFanart] = False
2016-07-14 02:43:01,765 (-8ea9530) :  INFO (__init__:47) - Prefs[GetTmdbPoster] = False
2016-07-14 02:43:01,765 (-8ea9530) :  INFO (__init__:47) - Prefs[GetASSPosters] = True
2016-07-14 02:43:01,766 (-8ea9530) :  INFO (__init__:47) - Prefs[localart] = True
2016-07-14 02:43:01,767 (-8ea9530) :  INFO (__init__:47) - Prefs[adult] = True
2016-07-14 02:43:01,767 (-8ea9530) :  INFO (__init__:47) - Prefs[GetPlexThemes] = False
2016-07-14 02:43:01,768 (-8ea9530) :  ERROR (__init__:50) - DefaultPrefs.json invalid. Value 'MinimumWeightasd' missing from 'DefaultPrefs.json', update it.

from hama.bundle.

ZeroQI avatar ZeroQI commented on September 26, 2024

Clever move to print during validation the settings
Well spotted error/behaviour

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

@ZeroQI
Well....seems the log post telling people that they need to resave their prefs is not enough.
Tried to see if we can assign the value if we find the None but nope.

def ValidatePrefs(): #     a = sum(getattr(t, name, 0) for name in "xyz")
  DefaultPrefs = {"GetTvdbFanart":  True,    "GetTvdbPosters": True, "GetTvdbBanners":   False, "GetAnidbPoster":   False,   "GetTmdbFanart": False, "GetTmdbPoster": False,   
                  "GetASSPosters":  False,   "localart":       True, "adult":            False, "GetPlexThemes":    False,   "MinimumWeight": "400", "SerieLanguage1": "main", 
                  "SerieLanguage2": "x-jat", "SerieLanguage3": "en", "EpisodeLanguage1": "en",  "EpisodeLanguage2": "x-jat", "https": False}
  try:  
    for key in DefaultPrefs.keys(): 
      if Prefs[key] == None:  Prefs[key] = DefaultPrefs[key]; Log.Warn("Prefs[%s] = %s (Preference value was 'None' so has been set to the default value.)" % (key, Prefs[key]))
      else:                                                   Log.Info("Prefs[%s] = %s" % (key, Prefs[key]))
  except Exception as e: err_str = "Value '%s' missing from 'DefaultPrefs.json', update it." % key;  Log.Error("DefaultPrefs.json invalid. " + err_str); Log.Error(e); return MessageContainer ('Error',   err_str)
  else:                  ok_str  = 'HAMA - Provided preference values are ok';                       Log.Info ("DefaultPrefs.json is valid. "+ ok_str );               return MessageContainer ('Success', ok_str )


2016-07-14 20:15:22,746 (-8e65530) :  INFO (__init__:50) - Prefs[SerieLanguage3] = x-jat
2016-07-14 20:15:22,747 (-8e65530) :  INFO (__init__:50) - Prefs[GetTmdbPoster] = False
2016-07-14 20:15:22,748 (-8e65530) :  ERROR (__init__:51) - DefaultPrefs.json invalid. Value 'MinimumWeight' missing from 'DefaultPrefs.json', update it.
2016-07-14 20:15:22,749 (-8e65530) :  ERROR (__init__:51) - 'PrefsKit' object does not support item assignment

Guess we have to check for the None and just use 400 for the test.

from hama.bundle.

ZeroQI avatar ZeroQI commented on September 26, 2024

seem like the json default is not retroactive and None pops up so yes, e have to check for the None and just use 400 for the test exactly as you stated

from hama.bundle.

EndOfLine369 avatar EndOfLine369 commented on September 26, 2024

Been a day, haven't seen any more complaints. Closing this ticket.

from hama.bundle.

Related Issues (20)

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.