├── run.sh ├── .env ├── img.png ├── .gitignore ├── CONTRIBUTING.md ├── requirements.txt ├── LICENSE ├── CODE_OF_CONDUCT.md ├── app.py └── README.md /run.sh: -------------------------------------------------------------------------------- 1 | nohup streamlit run app.py --server.port 5001 & -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | FLASK_API_URL=https://api.cinesimile.niweera.com/ 2 | -------------------------------------------------------------------------------- /img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Niweera/cinesimile/HEAD/img.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.idea 6 | /.vscode 7 | /.pnp 8 | .pnp.js 9 | /venv 10 | 11 | # testing 12 | /coverage 13 | /cypress/videos 14 | /cypress/screenshots 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | .env.local 22 | .env.development.local 23 | .env.test.local 24 | .env.production.local 25 | 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | Welcome to CineSimile! 📽️ 4 | CineSimile is an open source platform to find movie recommendations similar to a given movie. If you want to contribute to this project you can follow the following steps: 5 | 6 | 1. Fork and Clone the repository 7 | 2. Select an issue and work on it. 8 | 3. Create a Pull Request, 9 | 10 | # Additional resources 11 | 12 | - [How to Contribute to Open Source](http://opensource.guide/how-to-contribute/) 13 | - [FIRST TIMERS ONLY](https://www.firsttimersonly.com/) 14 | - [AWESOME FOR BEGINNERS](https://github.com/mungell/awesome-for-beginners) 15 | - [Useful Git Commands](https://github.com/joshnh/Git-Commands/blob/master/README.md) 16 | - [GitHub Training Kit](https://training.github.com/) 17 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | altair==5.2.0 2 | attrs==23.1.0 3 | blinker==1.7.0 4 | cachetools==5.3.2 5 | certifi==2023.11.17 6 | charset-normalizer==3.3.2 7 | click==8.1.7 8 | gitdb==4.0.11 9 | GitPython==3.1.40 10 | idna==3.6 11 | importlib-metadata==6.11.0 12 | Jinja2==3.1.2 13 | jsonschema==4.20.0 14 | jsonschema-specifications==2023.11.2 15 | markdown-it-py==3.0.0 16 | MarkupSafe==2.1.3 17 | mdurl==0.1.2 18 | numpy==1.26.2 19 | packaging==23.2 20 | pandas==2.1.4 21 | Pillow==10.1.0 22 | protobuf==4.25.1 23 | pyarrow==14.0.1 24 | pydeck==0.8.1b0 25 | Pygments==2.17.2 26 | python-dateutil==2.8.2 27 | python-dotenv==1.0.0 28 | pytz==2023.3.post1 29 | referencing==0.32.0 30 | requests==2.31.0 31 | rich==13.7.0 32 | rpds-py==0.13.2 33 | six==1.16.0 34 | smmap==5.0.1 35 | streamlit==1.29.0 36 | streamlit-searchbox==0.1.6 37 | tenacity==8.2.3 38 | toml==0.10.2 39 | toolz==0.12.0 40 | tornado==6.4 41 | typing_extensions==4.9.0 42 | tzdata==2023.3 43 | tzlocal==5.2 44 | urllib3==2.1.0 45 | validators==0.22.0 46 | watchdog==3.0.0 47 | zipp==3.17.0 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Nipuna Weerasekara 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at w.nipuna@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | from dotenv import load_dotenv 4 | import os 5 | import requests 6 | import streamlit as st 7 | from streamlit_searchbox import st_searchbox 8 | 9 | st.set_page_config(page_title="CineSimile", page_icon="🎬") 10 | 11 | # Load environment variables 12 | load_dotenv() 13 | 14 | # API Base URL 15 | API_BASE_URL = os.getenv("FLASK_API_URL") # Replace with your Flask API URL 16 | 17 | 18 | # Function to check API accessibility 19 | def is_api_accessible(): 20 | try: 21 | response = requests.get(API_BASE_URL) 22 | return response.status_code == 200 23 | except: 24 | return False 25 | 26 | 27 | # Check if the API is accessible 28 | api_accessible = is_api_accessible() 29 | 30 | 31 | # Function to get movie suggestions 32 | def get_movie_suggestions(query): 33 | response = requests.get(f"{API_BASE_URL}/suggest?query={query}") 34 | if response.status_code == 200: 35 | suggestions = response.json() 36 | return [f"{s['Name']} ({s['Date']})" for s in suggestions] 37 | return [] 38 | 39 | 40 | # Function to get movie recommendations 41 | def get_movie_recommendations(movie_name, movie_year, engine): 42 | response = requests.get( 43 | f"{API_BASE_URL}/recommend/{engine}?name={movie_name}&year={movie_year}" 44 | ) 45 | if response.status_code == 200: 46 | return response.json() 47 | return [] 48 | 49 | 50 | # Define a wrapper function for get_movie_suggestions to be used in st_searchbox 51 | def search_function(query): 52 | if query: 53 | return get_movie_suggestions(query) 54 | return [] 55 | 56 | 57 | # Streamlit UI 58 | 59 | st.title("🎬 CineSimile") 60 | st.subheader("AI is here to take over the world.") 61 | st.subheader("In the meantime, here's a good movie to watch!") 62 | 63 | # Disable UI if API is not accessible 64 | if not api_accessible: 65 | st.error("CineSimile-API is currently inaccessible. Please try again later.") 66 | st.stop() 67 | 68 | # Movie name input with autocomplete suggestions 69 | st.write("Enter the name of a movie") 70 | 71 | selected_movie = st_searchbox( 72 | label="", 73 | search_function=search_function, 74 | placeholder="Start typing...", 75 | help_text="Select a movie from the list", 76 | clear_on_submit=False, 77 | ) 78 | 79 | st.write("Find similar movies using:") 80 | # Buttons for each recommendation engine 81 | engines = ["cosine", "euclidean", "pearson", "jaccard", "manhattan"] 82 | # Create a row of columns for the buttons 83 | selected_engine = None 84 | cols = st.columns(len(engines)) 85 | for idx, engine in enumerate(engines): 86 | with cols[idx]: 87 | if st.button(engine.capitalize(), use_container_width=True): 88 | selected_engine = engine 89 | 90 | # Display recommendations 91 | if selected_engine and selected_movie: 92 | year_match = re.search(r"\((\d{4})\)", selected_movie) 93 | 94 | if not year_match: 95 | st.error("Please select a movie with a valid year") 96 | 97 | movie_year = int(year_match.group(1)) 98 | movie_name = selected_movie.replace(year_match.group(0), "").strip() 99 | 100 | similar_movies = get_movie_recommendations(movie_name, movie_year, selected_engine) 101 | 102 | # Display the movies and their posters horizontally 103 | cols = st.columns(len(similar_movies)) # Create columns 104 | for idx, movie in enumerate(similar_movies): 105 | with cols[idx]: 106 | st.image( 107 | movie.get("poster", {}).get( 108 | "poster", 109 | "https://s.studiobinder.com/wp-content/uploads/2017/12/Movie-Poster-Template-Dark-with-Image.jpg", 110 | ) 111 | ) 112 | st.markdown(f"**{movie['name']} ({movie['year']})**") 113 | elif selected_engine and not selected_movie: 114 | st.error("Please enter and select a movie name from the suggestions") 115 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Hacktoberfest](https://badgen.net/badge/hacktoberfest/friendly/pink)](CONTRIBUTING.md) 2 | [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/) 3 | [![MIT Licence](https://badges.frapsoft.com/os/mit/mit.svg?v=103)](https://opensource.org/licenses/mit-license.php) 4 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) 5 | [![Website cinesimile.niweera.com](https://img.shields.io/website-up-down-green-red/https/cinesimile.niweera.com.svg)](https://cinesimile.niweera.com/) 6 | [![GitHub forks](https://img.shields.io/github/forks/Niweera/cinesimile.svg?style=social&label=Fork)](https://GitHub.com/Niweera/cinesimile/network/) 7 | [![GitHub stars](https://img.shields.io/github/stars/Niweera/cinesimile.svg?style=social&label=Star)](https://GitHub.com/Niweera/cinesimile/stargazers/) 8 | [![GitHub watchers](https://img.shields.io/github/watchers/Niweera/cinesimile.svg?style=social&label=Watch&maxAge=2592000)](https://GitHub.com/Niweera/cinesimile/watchers/) 9 | [![GitHub contributors](https://img.shields.io/github/contributors/Niweera/cinesimile.svg)](https://GitHub.com/Niweera/cinesimile/graphs/contributors/) 10 | [![GitHub issues](https://img.shields.io/github/issues/Niweera/cinesimile.svg)](https://GitHub.com/Niweera/cinesimile/issues/) 11 | [![GitHub issues-closed](https://img.shields.io/github/issues-closed/Niweera/cinesimile.svg)](https://GitHub.com/Niweera/cinesimile/issues?q=is%3Aissue+is%3Aclosed) 12 | [![GitHub pull-requests](https://img.shields.io/github/issues-pr/Niweera/cinesimile.svg)](https://GitHub.com/Niweera/cinesimile/pulls/) 13 | [![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/Niweera/cinesimile.svg)](https://GitHub.com/Niweera/cinesimile/pulls/) 14 |

15 | [![forthebadge](https://forthebadge.com/images/badges/built-with-love.svg)](https://cinesimile.niweera.com/) 16 | [![forthebadge](https://forthebadge.com/images/badges/made-with-python.svg)](https://cinesimile.niweera.com/) 17 | [![forthebadge](https://forthebadge.com/images/badges/you-didnt-ask-for-this.svg)](https://cinesimile.niweera.com/) 18 | [![forthebadge](https://forthebadge.com/images/badges/winter-is-coming.svg)](https://cinesimile.niweera.com/) 19 | [![forthebadge](https://forthebadge.com/images/badges/check-it-out.svg)](https://cinesimile.niweera.com/) 20 | 21 |

🎬 CineSimile

22 |

AI is here to take over the world. In the meantime, here's a good movie to watch!

23 |
24 | 25 | ![img.png](img.png) 26 | 27 | ## About The Project 28 | 29 | CineSimile is a platform where you can find similar movies for a given movie. 30 | Now online at [cinesimile.niweera.com](https://cinesimile.niweera.com/). 31 | 32 | ### Machine Learning 33 | 34 | CineSimile is powered by machine learning to enhance the search capabilities and find a closer fit to your movie of choice. Similar technology is used by Netflix and Youtube to 35 | tailor recommendations to your personal choices. 36 | 37 | ### Technology Used 38 | 39 | - Streamlit - https://streamlit.io/ 40 | - Python 41 | 42 | ## Getting Started 43 | 44 | Thank you for showing interest in CineSimile, an open sourced platform to find similar movies for a given movie. Please follow the steps and you'll soon end up being an open source 45 | contributor and become a part of the Open Source Community😎. Please read the [CONTRIBUTING](https://github.com/Niweera/cinesimile/blob/master/CONTRIBUTING.md) document before 46 | starting to contribute to this project and learn about the intricacies of Contributing. 47 | 48 | 1. [Fork](https://github.com/Niweera/cinesimile/fork) the repository. 49 | 50 | 2. Clone the repository to your Local machine. 51 | 52 | ```bash 53 | $ git clone https://github.com//cinesimile.git 54 | ``` 55 | 56 | 3. Install Python packages. 57 | 58 | ```bash 59 | $ python3 -m pip install -r requirements.txt 60 | ``` 61 | 62 | 4. Start the React development server. 63 | 64 | ```bash 65 | $ streamlit run app.py 66 | ``` 67 | 68 | 5. Do something amazing and Creative(FYI, pick an issue from the [issue list](https://github.com/Niweera/cinesimile/issues), and add a comment stating that you're going to work on 69 | it.) 70 | 71 | 6. Commit and push the changes. 72 | 73 | ```bash 74 | $ git add . 75 | 76 | $ git commit -m "your commit message (make it meaningful and short)" 77 | 78 | $ git push origin master 79 | ``` 80 | 81 | 7. Finally, create a [pull request](https://www.youtube.com/watch?v=OHV64qh-uyY). 82 | 83 | ## Additional Information 84 | 85 | 9. If you are creating a new pull request please update your fork. 86 | 87 | ```bash 88 | $ git pull upstream main 89 | ``` 90 | 91 | Do this before creating another pull request. By doing this, your fork will be up-to-date with the main repository. 92 | 93 | ## License 94 | 95 | Distributed under the MIT License. See [LICENSE](https://github.com/Niweera/cinesimile/blob/master/LICENSE) for more information. 96 | 97 | ### Special thanks to [Dr. Adarsh Prasad Behera](https://scholar.google.com/citations?user=ce1y_FMAAAAJ&hl=en&oi=ao). 98 | --------------------------------------------------------------------------------