Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x #12

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

x #12

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .DS_Store
Binary file not shown.
57 changes: 57 additions & 0 deletions set_crafter/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Contributing to SetCrafter AI

We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's:

- Reporting a bug
- Discussing the current state of the code
- Submitting a fix
- Proposing new features
- Becoming a maintainer

## We Develop with Github

We use github to host code, to track issues and feature requests, as well as accept pull requests.

## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests

Pull requests are the best way to propose changes to the codebase. We actively welcome your pull requests:

1. Fork the repo and create your branch from `main`.
2. If you've added code that should be tested, add tests.
3. If you've changed APIs, update the documentation.
4. Ensure the test suite passes.
5. Make sure your code lints.
6. Issue that pull request!

## Any contributions you make will be under the MIT Software License

In short, when you submit code changes, your submissions are understood to be under the same [MIT License](https://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern.

## Report bugs using Github's [issues](https://github.com/briandk/transcriptase-atom/issues)

We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/briandk/transcriptase-atom/issues); it's that easy!

## Write bug reports with detail, background, and sample code

**Great Bug Reports** tend to have:

- A quick summary and/or background
- Steps to reproduce
- Be specific!
- Give sample code if you can.
- What you expected would happen
- What actually happens
- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)

## Use a Consistent Coding Style

* 2 spaces for indentation rather than tabs
* You can try running `npm run lint` for style unification

## License

By contributing, you agree that your contributions will be licensed under its MIT License.

## References

This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js)
4 changes: 2 additions & 2 deletions LICENSE → set_crafter/LICENSE.md
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2023 Myuzeo Labs
Copyright (c) 2022 SetCrafter AI

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
23 changes: 15 additions & 8 deletions README.md → set_crafter/README.md
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SetCraifter
# SetCraifter

## Introduction

Expand Down Expand Up @@ -27,9 +27,10 @@ SetCrafter AI is a tentative project designed to revolutionize the way DJs organ
### Usage

Run the main script to start categorizing and curating your DJ library:

## Contribution

We welcome contributions to SetCrafter AI. Please read the [CONTRIBUTING.md](CONTRIBUTING.md) file for guidelines on how to contribute.
We welcome contributions to SetCrafter AI. Please read the CONTRIBUTING.md file for guidelines on how to contribute.

## Alternative Solutions

Expand All @@ -38,19 +39,18 @@ We welcome contributions to SetCrafter AI. Please read the [CONTRIBUTING.md](CON

## License

SetCrafter AI is licensed under the MIT License. See the [LICENSE.md](LICENSE.md) file for details.
SetCrafter AI is licensed under the MIT License. See the LICENSE.md file for details.

## Contact

For any inquiries or feedback, please reach out to [username@email.com](mailto:username@email.com).
For any inquiries or feedback, please reach out to username@email.com.

## Acknowledgments

Special thanks to the music community for inspiring this innovative approach to DJ library organization.



=======

# Set Crafter Tool

Set Crafter is a tool designed to assist DJs in crafting their music sets with the help of AI-driven recommendations and data analysis.
Expand All @@ -65,36 +65,44 @@ Set Crafter is a tool designed to assist DJs in crafting their music sets with t
## Modules

### Data Preprocessing Module

- `DJLibraryDataExtractor`: Extracts data from a DJ's music library
- `DataPreprocessor`: Processes the data for AI model consumption
- `SpotifyDataDownloader`: Downloads track data from Spotify

### AI Models Module

- `TrackCategorizer`: Categorizes tracks based on their features
- `SetCurator`: Curates music sets based on the categorized tracks
- `ModelTrainingDataBuilder`: Prepares datasets for training AI models

### Main Application Module

- `SetCrafterApp`: Coordinates modules and provides the user interface

## Libraries

- spotipy
- pandas
- scikit-learn
- flask
- streamlit

## Backend Development

- Endpoints for Spotify authentication and track downloading

## Frontend Development

- Implemented using Streamlit for a user-friendly interface

## Security and Error Handling

- OAuth 2.0 implementation for secure Spotify authentication
- Robust error handling and logging mechanisms

## Testing and Deployment

- Comprehensive testing of backend and frontend components
- Deployment strategies for the Flask and Streamlit applications

Expand All @@ -104,5 +112,4 @@ Instructions on how to set up and run Set Crafter will be provided here.

## License

This project is licensed under the MIT License - see the LICENSE file for details.

This project is licensed under the MIT License - see the LICENSE file for details.
18 changes: 18 additions & 0 deletions set_crafter/ai_models/model_training_data_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
```python
import pandas as pd
from sklearn.model_selection import train_test_split

class ModelTrainingDataBuilder:
def __init__(self, track_data):
self.track_data = track_data

def build_training_data(self):
# Split the data into features and target
X = self.track_data.drop('category', axis=1)
y = self.track_data['category']

# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

return X_train, X_test, y_train, y_test
```
35 changes: 35 additions & 0 deletions set_crafter/ai_models/set_curator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
```python
from sklearn.neighbors import NearestNeighbors
import pandas as pd

class SetCurator:
def __init__(self, track_data):
self.track_data = track_data
self.curated_set = None

def curate_set(self):
# Use nearest neighbors to curate a set based on track features
model = NearestNeighbors(n_neighbors=7)
model.fit(self.track_data)

# Generate a set starting with a random track
start_track = self.track_data.sample(1)
set_indices = model.kneighbors(start_track, return_distance=False)

# Create a curated set dataframe
self.curated_set = self.track_data.iloc[set_indices[0]]

return self.curated_set

def save_curated_set(self, filename):
# Save the curated set to a CSV file
self.curated_set.to_csv(filename, index=False)

def load_curated_set(self, filename):
# Load a curated set from a CSV file
self.curated_set = pd.read_csv(filename)

def get_curated_set(self):
# Return the curated set
return self.curated_set
```
30 changes: 30 additions & 0 deletions set_crafter/ai_models/track_categorizer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
```python
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd

class TrackCategorizer:
def __init__(self):
self.model = KNeighborsClassifier()

def build_training_data(self, track_data):
# Extract features and labels from track_data
features = track_data.drop('category', axis=1)
labels = track_data['category']
return features, labels

def train_model(self, features, labels):
self.model.fit(features, labels)

def categorize_track(self, track):
# Predict the category of a single track
category = self.model.predict([track])
return category[0]

if __name__ == "__main__":
track_data = pd.read_csv('track_data.csv')
categorizer = TrackCategorizer()
features, labels = categorizer.build_training_data(track_data)
categorizer.train_model(features, labels)
test_track = [0.6, 0.7, 120] # Example track data
print(categorizer.categorize_track(test_track))
```
45 changes: 45 additions & 0 deletions set_crafter/app/set_crafter_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
```python
import os
from set_crafter.data_preprocessing.dj_library_data_extractor import DJLibraryDataExtractor
from set_crafter.data_preprocessing.data_preprocessor import DataPreprocessor
from set_crafter.data_preprocessing.spotify_data_downloader import SpotifyDataDownloader
from set_crafter.ai_models.track_categorizer import TrackCategorizer
from set_crafter.ai_models.set_curator import SetCurator
from set_crafter.ai_models.model_training_data_builder import ModelTrainingDataBuilder

class SetCrafterApp:
def __init__(self):
self.spotify_credentials = os.getenv('SPOTIFY_CREDENTIALS')
self.data_extractor = DJLibraryDataExtractor()
self.data_preprocessor = DataPreprocessor()
self.data_downloader = SpotifyDataDownloader(self.spotify_credentials)
self.track_categorizer = TrackCategorizer()
self.set_curator = SetCurator()
self.training_data_builder = ModelTrainingDataBuilder()

def run(self):
# Extract data from DJ's library
track_data = self.data_extractor.extract_data()

# Download additional track data from Spotify
track_data = self.data_downloader.download_data(track_data)

# Preprocess the data for AI model consumption
track_data = self.data_preprocessor.preprocess_data(track_data)

# Build training data for AI models
training_data = self.training_data_builder.build_training_data(track_data)

# Categorize tracks based on their features
categorized_tracks = self.track_categorizer.categorize_track(training_data)

# Curate music sets based on the categorized tracks
curated_sets = self.set_curator.curate_set(categorized_tracks)

return curated_sets

if __name__ == "__main__":
app = SetCrafterApp()
curated_sets = app.run()
print(curated_sets)
```
53 changes: 53 additions & 0 deletions set_crafter/backend/spotify_auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
```python
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from flask import Flask, request, redirect, session
import os
from ..config import spotify_credentials

app = Flask(__name__)

# Set the secret key to some random bytes. Keep this really secret!
app.secret_key = os.urandom(16)

@app.route('/')
def index():
auth_url = create_spotify_oauth().get_authorize_url()
return redirect(auth_url)

@app.route('/callback')
def callback():
code = request.args.get('code')
token_info = create_spotify_oauth().get_access_token(code)
session["token_info"] = token_info
return redirect("AuthenticationSuccess")

def create_spotify_oauth():
return SpotifyOAuth(
client_id=spotify_credentials["client_id"],
client_secret=spotify_credentials["client_secret"],
redirect_uri=spotify_credentials["redirect_uri"],
scope="user-library-read"
)

def get_token(session):
token_valid = False
token_info = session.get("token_info", {})

# Checking if the session already has a token.
if not (session.get('token_info', False)):
token_valid = False
else:
now = int(time.time())
is_token_expired = session['token_info']['expires_at'] - now < 60

# If the token is expired, refresh it
if (is_token_expired):
sp_oauth = create_spotify_oauth()
token_info = sp_oauth.refresh_access_token(session['token_info']['refresh_token'])
token_valid = True
return token_info, token_valid

if __name__ == "__main__":
app.run(debug=True, port=spotify_credentials["port"])
```
16 changes: 16 additions & 0 deletions set_crafter/backend/track_downloader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
```python
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from ..config import spotify_credentials

class SpotifyDataDownloader:
def __init__(self):
self.sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=spotify_credentials['client_id'],
client_secret=spotify_credentials['client_secret'],
redirect_uri=spotify_credentials['redirect_uri'],
scope=spotify_credentials['scope']))

def download_data(self, track_id):
track_data = self.sp.track(track_id)
return track_data
```
11 changes: 11 additions & 0 deletions set_crafter/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```python
# Configuration file for SetCrafter

# Spotify API credentials
spotify_credentials = {
"client_id": "<your_spotify_client_id>",
"client_secret": "<your_spotify_client_secret>",
"redirect_uri": "<your_spotify_redirect_uri>",
"username": "<your_spotify_username>"
}
```
Loading