Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: inostia/discograph
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: josiah-wolf-oberholtzer/discograph
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Able to merge. These branches can be automatically merged.

Commits on Oct 2, 2015

  1. Copy the full SHA
    898fdff View commit details
  2. Copy the full SHA
    d13f83a View commit details
  3. Copy the full SHA
    df5794b View commit details
  4. Copy the full SHA
    595c9cd View commit details
  5. Copy the full SHA
    5d4bea2 View commit details
  6. Copy the full SHA
    7e9f28f View commit details
  7. Copy the full SHA
    2436f25 View commit details
  8. Copy the full SHA
    aba30ad View commit details
  9. Copy the full SHA
    660bb6c View commit details

Commits on Oct 3, 2015

  1. Copy the full SHA
    7217be0 View commit details
  2. Copy the full SHA
    b47ff43 View commit details
  3. Copy the full SHA
    4b8c8b6 View commit details
  4. Copy the full SHA
    f39271a View commit details
  5. Copy the full SHA
    5c01452 View commit details
  6. Copy the full SHA
    2d7eac5 View commit details
  7. Copy the full SHA
    53739bb View commit details
  8. Copy the full SHA
    c8f2872 View commit details
  9. Copy the full SHA
    133c7d1 View commit details
  10. Copy the full SHA
    1aec346 View commit details
  11. Copy the full SHA
    633bb39 View commit details
  12. Copy the full SHA
    495da6f View commit details
  13. Copy the full SHA
    230f471 View commit details
  14. Copy the full SHA
    b95b631 View commit details
  15. Copy the full SHA
    4134b99 View commit details
  16. Copy the full SHA
    0ee9bca View commit details
  17. Copy the full SHA
    b258cad View commit details
  18. Copy the full SHA
    4a46825 View commit details
  19. Copy the full SHA
    2471677 View commit details
  20. Copy the full SHA
    64487c2 View commit details
  21. Copy the full SHA
    1a1c515 View commit details
  22. Copy the full SHA
    cf45d63 View commit details
  23. Copy the full SHA
    4366c1b View commit details
  24. Copy the full SHA
    8df63b7 View commit details
  25. Copy the full SHA
    5de1f94 View commit details
  26. Copy the full SHA
    590924a View commit details
  27. Copy the full SHA
    424c032 View commit details
  28. Copy the full SHA
    87f5b7c View commit details
  29. Copy the full SHA
    8d4c8f3 View commit details

Commits on Oct 4, 2015

  1. Copy the full SHA
    c26b339 View commit details
  2. Copy the full SHA
    0c1732f View commit details
  3. Copy the full SHA
    7b96abe View commit details
  4. Copy the full SHA
    d9394c4 View commit details
  5. Copy the full SHA
    8e73367 View commit details
  6. Copy the full SHA
    ae82155 View commit details
  7. Copy the full SHA
    009dc4e View commit details
  8. Copy the full SHA
    f7d35c3 View commit details
  9. Copy the full SHA
    1689dbf View commit details
  10. Copy the full SHA
    f8a2400 View commit details
  11. Copy the full SHA
    ed644ea View commit details

Commits on Oct 5, 2015

  1. Copy the full SHA
    ef45563 View commit details
Showing with 14,493 additions and 8,403 deletions.
  1. +105 −0 .ackrc
  2. +3 −1 .gitignore
  3. +47 −0 DEPLOYMENT_NOTES.md
  4. +35 −2 README.md
  5. BIN discograph.png
  6. +3 −1 discograph/.gitignore
  7. +61 −0 discograph/Gruntfile.js
  8. +41 −19 discograph/api.py
  9. +49 −29 discograph/app.py
  10. +22 −0 discograph/config.py
  11. +0 −2 discograph/configuration/discograph.example.conf
  12. +3 −2 discograph/configuration/gunicorn.conf
  13. +4 −1 discograph/data/.gitignore
  14. BIN discograph/data/discogs_test_artists.xml.gz
  15. BIN discograph/data/discogs_test_labels.xml.gz
  16. BIN discograph/data/discogs_test_masters.xml.gz
  17. BIN discograph/data/discogs_test_releases.xml.gz
  18. +1 −0 discograph/docs/.gitignore
  19. +229 −0 discograph/docs/ABOUT.md
  20. +7 −0 discograph/docs/Makefile
  21. +35 −0 discograph/docs/graph.dot
  22. +4 −21 discograph/exceptions.py
  23. +185 −2 discograph/helpers.py
  24. +34 −41 discograph/library/Bootstrapper.py
  25. +857 −0 discograph/library/CreditRole.py
  26. +0 −153 discograph/library/DiscographAPI.py
  27. +52 −0 discograph/library/DiscographTestCase.py
  28. +681 −0 discograph/library/PostgresEntity.py
  29. +56 −0 discograph/library/PostgresMaster.py
  30. +187 −0 discograph/library/PostgresModel.py
  31. +489 −0 discograph/library/PostgresRelation.py
  32. +388 −0 discograph/library/PostgresRelease.py
  33. +614 −325 discograph/library/RelationGrapher.py
  34. +154 −0 discograph/library/TrellisNode.py
  35. +1 −5 discograph/library/__init__.py
  36. +0 −325 discograph/library/mongo/Artist.py
  37. +0 −42 discograph/library/mongo/ArtistCredit.py
  38. +0 −43 discograph/library/mongo/ArtistReference.py
  39. +0 −30 discograph/library/mongo/CompanyCredit.py
  40. +0 −786 discograph/library/mongo/CreditRole.py
  41. +0 −33 discograph/library/mongo/Format.py
  42. +0 −22 discograph/library/mongo/Identifier.py
  43. +0 −206 discograph/library/mongo/Label.py
  44. +0 −21 discograph/library/mongo/LabelCredit.py
  45. +0 −44 discograph/library/mongo/LabelReference.py
  46. +0 −94 discograph/library/mongo/Master.py
  47. +0 −56 discograph/library/mongo/MongoModel.py
  48. +0 −526 discograph/library/mongo/Relation.py
  49. +0 −245 discograph/library/mongo/Release.py
  50. +0 −33 discograph/library/mongo/Track.py
  51. +0 −8 discograph/library/mongo/__init__.py
  52. +0 −8 discograph/library/postgres/__init__.py
  53. +0 −43 discograph/library/sqlite/SqliteArtist.py
  54. +0 −9 discograph/library/sqlite/SqliteFTSArtist.py
  55. +0 −43 discograph/library/sqlite/SqliteLabel.py
  56. +0 −71 discograph/library/sqlite/SqliteModel.py
  57. +0 −116 discograph/library/sqlite/SqliteRelation.py
  58. +0 −8 discograph/library/sqlite/__init__.py
  59. +0 −71 discograph/library/test/test_ArtistCredit_from_elements.py
  60. +0 −97 discograph/library/test/test_Artist_from_element.py
  61. +15 −15 ...raph/library/test/{test_Release_parse_release_date.py → test_Bootstrapper_element_to_datetime.py}
  62. +38 −39 discograph/library/test/{test_ArtistRole_from_element.py → test_CreditRole_from_element.py}
  63. +0 −71 discograph/library/test/test_Label_from_element.py
  64. +125 −0 discograph/library/test/test_PostgresEntity.py
  65. +123 −0 discograph/library/test/test_PostgresEntity_structural_roles_to_relations.py
  66. +1,735 −0 discograph/library/test/test_PostgresRelation_from_release.py
  67. +425 −0 discograph/library/test/test_PostgresRelease.py
  68. +1,090 −909 discograph/library/test/test_RelationGrapher.py
  69. +0 −94 discograph/library/test/test_Relation_from_artist.py
  70. +0 −88 discograph/library/test/test_Relation_from_label.py
  71. +0 −849 discograph/library/test/test_Relation_from_release.py
  72. +0 −1,469 discograph/library/test/test_Release_from_element.py
  73. +23 −0 discograph/package.json
  74. +1 −0 discograph/source/css/.gititnore
  75. +363 −0 discograph/source/css/discograph.less
  76. +1 −0 discograph/source/js/.gititnore
  77. +16 −0 discograph/source/js/color.js
  78. +433 −0 discograph/source/js/fsm.js
  79. +16 −0 discograph/source/js/index.js
  80. +44 −0 discograph/source/js/init.js
  81. +146 −0 discograph/source/js/loading.js
  82. +163 −0 discograph/source/js/network/forceLayout.js
  83. +19 −0 discograph/source/js/network/halo.js
  84. +10 −0 discograph/source/js/network/hull.js
  85. +10 −0 discograph/source/js/network/index.js
  86. +14 −0 discograph/source/js/network/init.js
  87. +75 −0 discograph/source/js/network/link.js
  88. +150 −0 discograph/source/js/network/node.js
  89. +33 −0 discograph/source/js/network/object.js
  90. +35 −0 discograph/source/js/network/paging.js
  91. +43 −0 discograph/source/js/network/text.js
  92. +105 −0 discograph/source/js/network/tick.js
  93. +103 −0 discograph/source/js/relations.js
  94. +76 −0 discograph/source/js/svg.js
  95. +80 −0 discograph/source/js/typeahead.js
  96. +1 −0 discograph/static/css/bootstrap-multiselect.css
  97. +305 −133 discograph/static/css/discograph.css
  98. +7 −2 discograph/static/css/typeahead-bootstrap.css
  99. +0 −19 discograph/static/js/dg/dg.color.js
  100. +0 −856 discograph/static/js/dg/dg.graph.js
  101. +0 −31 discograph/static/js/dg/dg.history.js
  102. +0 −12 discograph/static/js/dg/dg.js
  103. +0 −74 discograph/static/js/dg/dg.typeahead.js
  104. +1,651 −0 discograph/static/js/discograph.js
  105. +1,416 −0 discograph/static/js/vendor/bootstrap-multiselect.js
  106. +324 −0 discograph/static/js/vendor/d3-tip.js
  107. +596 −0 discograph/static/js/vendor/machina.js
  108. +0 −26 discograph/templates/404.html
  109. +0 −26 discograph/templates/500.html
  110. +23 −3 discograph/templates/{400.html → error.html}
  111. +34 −41 discograph/templates/index.html
  112. +12 −11 discograph/templates/modal-welcome.html
  113. +4 −2 discograph/templates/modal-what.html
  114. +13 −18 discograph/templates/modal-who.html
  115. +37 −5 discograph/templates/nav-bottom.html
  116. +45 −0 discograph/templates/offline.html
  117. +20 −0 discograph/templates/paging.html
  118. +55 −0 discograph/test/test_api.py
  119. +25 −0 discograph/test/test_ui.py
  120. +63 −24 discograph/ui.py
  121. +2 −1 requirements.txt
  122. +3 −1 setup.py
105 changes: 105 additions & 0 deletions .ackrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
--ignore-ack-defaults
--ignore-directory=is:.bzr
--ignore-directory=is:.cdv
--ignore-directory=is:~.dep
--ignore-directory=is:~.dot
--ignore-directory=is:~.nib
--ignore-directory=is:~.plst
--ignore-directory=is:.git
--ignore-directory=is:.hg
--ignore-directory=is:.pc
--ignore-directory=is:.svn
--ignore-directory=is:_MTN
--ignore-directory=is:CVS
--ignore-directory=is:RCS
--ignore-directory=is:SCCS
--ignore-directory=is:_darcs
--ignore-directory=is:_sgbak
--ignore-directory=is:autom4te.cache
--ignore-directory=is:blib
--ignore-directory=is:_build
--ignore-directory=is:cover_db
--ignore-file=ext:bak
--ignore-file=match:/~$/
--ignore-file=match:/^#.+#$/
--ignore-file=match:/[._].*\.swp$/
--ignore-file=match:/core\.\d+$/
--ignore-file=match:/[.]min[.]js$/
--ignore-file=match:/[.]js[.]min$/
--ignore-file=match:/[.]min[.]css$/
--ignore-file=match:/[.]css[.]min$/
--type-add=perl:ext:pl,pm,pod,t
--type-add=perl:firstlinematch:/^#!.*\bperl/
--type-add=make:ext:mk
--type-add=make:ext:mak
--type-add=make:is:makefile
--type-add=make:is:Makefile
--type-add=make:is:GNUmakefile
--type-add=rake:is:Rakefile
--type-add=cmake:is:CMakeLists.txt
--type-add=cmake:ext:cmake
--type-add=actionscript:ext:as,mxml
--type-add=ada:ext:ada,adb,ads
--type-add=asp:ext:asp
--type-add=aspx:ext:master,ascx,asmx,aspx,svc
--type-add=asm:ext:asm,s
--type-add=batch:ext:bat,cmd
--type-add=cfmx:ext:cfc,cfm,cfml
--type-add=clojure:ext:clj
--type-add=cc:ext:c,h,xs
--type-add=hh:ext:h
--type-add=cpp:ext:cpp,cc,cxx,m,hpp,hh,h,hxx
--type-add=csharp:ext:cs
--type-add=css:ext:css
--type-add=dart:ext:dart
--type-add=delphi:ext:pas,int,dfm,nfm,dof,dpk,dproj,groupproj,bdsgroup,bdsproj
--type-add=elisp:ext:el
--type-add=erlang:ext:erl,hrl
--type-add=fortran:ext:f,f77,f90,f95,f03,for,ftn,fpp
--type-add=go:ext:go
--type-add=groovy:ext:groovy,gtmpl,gpp,grunit,gradle
--type-add=haskell:ext:hs,lhs
--type-add=html:ext:htm,html
--type-add=java:ext:java,properties
--type-add=js:ext:js
--type-add=jsp:ext:jsp,jspx,jhtm,jhtml
--type-add=lisp:ext:lisp,lsp
--type-add=lua:ext:lua
--type-add=objc:ext:m,h
--type-add=objcpp:ext:mm,h
--type-add=ocaml:ext:ml,mli
--type-add=parrot:ext:pir,pasm,pmc,ops,pod,pg,tg
--type-add=php:ext:php,phpt,php3,php4,php5,phtml
--type-add=php:firstlinematch:/^#!.*\bphp/
--type-add=plone:ext:pt,cpt,metadata,cpy,py
--type-add=python:ext:py
--type-add=python:firstlinematch:/^#!.*\bpython/
--type-add=rr:ext:R
--type-add=ruby:ext:rb,rhtml,rjs,rxml,erb,rake,spec
--type-add=ruby:is:Rakefile
--type-add=ruby:firstlinematch:/^#!.*\bruby/
--type-add=rust:ext:rs
--type-add=scala:ext:scala
--type-add=scheme:ext:scm,ss
--type-add=shell:ext:sh,bash,csh,tcsh,ksh,zsh,fish
--type-add=shell:firstlinematch:/^#!.*\b(?:ba|t?c|k|z|fi)?sh\b/
--type-add=smalltalk:ext:st
--type-add=sql:ext:sql,ctl
--type-add=tcl:ext:tcl,itcl,itk
--type-add=tex:ext:tex,cls,sty
--type-add=tt:ext:tt,tt2,ttml
--type-add=vb:ext:bas,cls,frm,ctl,vb,resx
--type-add=verilog:ext:v,vh,sv
--type-add=vhdl:ext:vhd,vhdl
--type-add=vim:ext:vim
--type-add=xml:ext:xml,dtd,xsl,xslt,ent
--type-add=xml:firstlinematch:/<[?]xml/
--type-add=yaml:ext:yaml,yml

--ignore-directory=is:.tox
--ignore-directory=is:__pycache__
--ignore-directory=is:data
--ignore-directory=is:src
--ignore-directory=is:dist
--ignore-directory=is:build
--ignore-directory=is:discograph.egg-info
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -59,4 +59,6 @@ target/
# discograph
tmp/
src/
logs/
logs/
discograph.cfg
discograph.conf
47 changes: 47 additions & 0 deletions DEPLOYMENT_NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# DEPLOYMENT NOTES

These are specific to the deployment on a CentOS 6.5 VPS at http://discograph.mbrsi.org.

Disco/graph was designed for Python 3.4+ and (currently) makes use of Sqlite3 with FTS4 support compiled in.

These notes outline some of the build commands used during the process of determining the correct deployment in the above-described environment.

## Python

Python 3.4, installed manually in /usr/local/.

Linked against manually installed Sqlite3.

LD_RUN_PATH=/usr/local/sqlite-3.8.11/lib ./configure \
LDFLAGS="-L/usr/local/sqlite-3.8.11/lib -Wl,-rpath /usr/local/lib" \
CPPFLAGS="-I/usr/local/sqlite-3.8.11/include" \
--prefix=/usr/local \
--enable-shared

LD_RUN_PATH=/usr/local/sqlite-3.8.11/lib make altinstall

## Sqlite

Sqlite 3.8.11, installed manually in /usr/local/sqlite-3.8.11/.

Compiled with FTS3 and FTS4.

## apsw

APSW obviates the need for compiling Sqlite 3.8.11 into Python.

python setup.py fetch --all build --enable-all-extensions install test

## supervisord

It's crucial to set LD_LIBRARY_PATH in the supervisord configuration:

[program:discograph]
directory = /home/mbrsi/subdomains/discograph
command = /home/mbrsi/subdomains/discograph/bin/gunicorn --conf gunicorn.conf discograph:app
user = mbrsi
autostart = true
autorestart = false
redirect_stderr = true
stdout_logfile = /tmp/discograph.log
environment=HOME=/home/mbrsi,LD_LIBRARY_PATH=/usr/local/sqlite-3.8.11/lib:/usr/local/lib,LD_RUN_PATH=/usr/local/sqlite-3.8.11/lib
37 changes: 35 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
# discograph
# disco/graph

Social Graphing for the Discogs Database
[Disco/graph](http://discograph.mbrsi.org/) - Social Graphing for the Discogs
Database

## What is this?

Disco/graph is an interactive visualization of the relationships between
musicians, bands and labels. :notes:

All of Disco/graph's data is derived from the [Discogs](http://www.discogs.com)
discography database: nearly 4 million artists, 1 million labels, and 7 million
releases creating a network of nearly 70 million different relationships.

## How do I use this?

Visit the live site at http://discograph.mbrsi.org/.

Type an artist name into the search box and go!

What do all of these symbols mean?

* Small circles represent artists.
* Large circles represent bands.
* Solid lines show artist/band and sublabel/parent-label membership.
* Dashed lines show pseudonyms between artists (*AKA*).
* Dotted lines show all kinds of other relationships, like "artist X played
guitar for artist Y" or "artist P did cover art for label Q".

The graph shows at most 100 entities at a time, so double-click on any circle
containing a plus-sign to reveal more connections.

As mentioned, the data used is straight from Discogs, so if there are any
omissions or errors, please add or correct the artist on their website.

![The "Morris Day" Network](/discograph.png)
Binary file added discograph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion discograph/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
discograph.conf
discograph.conf
node_modules
locals.py
61 changes: 61 additions & 0 deletions discograph/Gruntfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
less: {
build: {
options: {
//compress: true,
//yuicompress: true,
//optimization: 2
},
files: {
'static/css/discograph.css': 'source/css/discograph.less'
},
},
},
smash: {
bundle: {
src: 'source/js/index.js',
dest: 'static/js/discograph.js',
},
},
jsbeautifier: {
files: ['static/js/discograph.js'],
options: {
braceStyle: 'collapse',
breakChainedMethods: true,
e4x: false,
evalCode: false,
indentChar: ' ',
indentLevel: 4,
indentSize: 2,
indentWithTabs: false,
jslintHappy: true,
keepArrayIndentation: false,
keepFunctionIndentation: false,
maxPreserveNewlines: 0,
preserveNewLines: false,
spaceBeforeConditional: true,
spaceInParen: true,
unescapeStrings: false,
wrapLineLength: 79,
endWithNewline: true
}
},
watch: {
js: {
files: ['source/js/**'],
tasks: ['smash', 'jsbeautifier'],
},
css: {
files: ['source/css/**'],
tasks: ['less'],
}
}
});
grunt.loadNpmTasks("grunt-jsbeautifier");
grunt.loadNpmTasks('grunt-smash');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['smash', 'jsbeautifier', 'less', 'watch']);
};
60 changes: 41 additions & 19 deletions discograph/api.py
Original file line number Diff line number Diff line change
@@ -11,38 +11,60 @@
blueprint = Blueprint('api', __name__, template_folder='templates')


@blueprint.route('/random')
@blueprint.route('/<entity_type>/relations/<int:entity_id>')
@decorators.limit(max_requests=60, period=60)
def route__api__random():
role_names = ['Alias', 'Member Of']
entity_type, entity_id = helpers.discograph_api.get_random_entity(role_names=role_names)
entity_type = {
1: 'artist',
2: 'label',
}[entity_type]
data = {'center': '{}-{}'.format(entity_type, entity_id)}
def route__api__entity_type__relations__entity_id(entity_type, entity_id):
if entity_type not in ('artist', 'label'):
raise exceptions.APIError(message='Bad Entity Type', status_code=404)
data = helpers.get_relations(
entity_id,
entity_type,
)
if data is None:
raise exceptions.APIError(message='No Data', status_code=400)
return jsonify(data)


@blueprint.route('/artist/network/<int:artist_id>')
@blueprint.route('/<entity_type>/network/<int:entity_id>')
@decorators.limit(max_requests=60, period=60)
def route__api__artist__network__artist_id(artist_id):
def route__api__entity_type__network__entity_id(entity_type, entity_id):
if entity_type not in ('artist', 'label'):
raise exceptions.APIError(message='Bad Entity Type', status_code=404)
parsed_args = helpers.parse_request_args(request.args)
original_roles, original_year = parsed_args
on_mobile = request.MOBILE
data = helpers.discograph_api.get_artist_network(artist_id, on_mobile=on_mobile)
data = helpers.get_network(
entity_id,
entity_type,
on_mobile=on_mobile,
cache=True,
roles=original_roles,
)
if data is None:
raise exceptions.APIError()
raise exceptions.APIError(message='No Data', status_code=400)
return jsonify(data)


@blueprint.route('/search/<search_string>')
@decorators.limit(max_requests=120, period=60)
def route__api__search(search_string):
data = helpers.discograph_api.search_entities(search_string)
data = helpers.search_entities(search_string)
return jsonify(data)


@blueprint.route('/ping')
@decorators.limit(max_requests=200, period=60)
def route__api__ping():
print('PING', request.remote_addr)
return jsonify({'ping': True})
@blueprint.route('/random')
@decorators.limit(max_requests=60, period=60)
def route__api__random():
parsed_args = helpers.parse_request_args(request.args)
original_roles, original_year = parsed_args
print('Roles:', original_roles)
entity_type, entity_id = helpers.get_random_entity(
roles=original_roles,
)
print(' Found: {}-{}'.format(entity_type, entity_id))
entity_type = {
1: 'artist',
2: 'label',
}[entity_type]
data = {'center': '{}-{}'.format(entity_type, entity_id)}
return jsonify(data)
Loading