Also fixed the episode rating text getting cut off at certain dimensions by enforcing its minimum width at which a double digit rating is still visible (eg 7.1)
Because this makes more sense to reuse the logic and also because APIRequest is now only locally accessible in the tmdb package, to stop me from using anywhere else, should always use an exposed function from the package so it can be reused.
It is no longer very pertinent since all watched data isn't stored in the browser. When we redirect the user to their list, fresh data is already fetched.
I'm upset that the textarea closing tag is being put on the same line instead of new lined, but I couldn't figure out what changed, so I'll cry in silence and hope it gets fixed one day.
Since the default CheckRedirect has been replaced with ours, we won't get the default protection of erroring after 10 redirects, so i've copied that back in from the std implementation
The Plex integration used bare http.Client values with no CheckRedirect
policy, so they followed redirects automatically. net/http strips the
standard sensitive headers on a cross-host redirect but not custom-named
headers, so the Plex token carried in X-Plex-Token was forwarded verbatim
to any host the configured PLEX_HOST redirected to, disclosing the
credential.
Route all Plex outbound calls through a shared client whose CheckRedirect
policy deletes X-Plex-Token when the redirect target host differs from the
original request host. Includes a regression test.
Signed-off-by: tonghuaroot <tonghuaroot@gmail.com>
I think the plex api default used to be JSON, which is why it worked, but I guess they changed it to XML. Adding this header asks for JSON response again.
Based on PR by goestav: https://github.com/sbondCo/Watcharr/pull/1055
Different in these ways:
- Using $derived here for `ws` variable
- Using z-index to allow status button to be clicked while spoilers are hidden
- Don't hide spoilers again (if they are shown) when episode is deleted
Also refactored `handleStatusClick()` a bit by removing the redundant `ws` lookup (it can now just use `we` set at the top of the component).
Co-Authored-By: Goestav <27970303+goestav@users.noreply.github.com>
- Create a better (more) re-usable flow for downloading images to disk and inserting images into the db
- Validate images properly by reading them fully and using DecodeConfig
- Fix some security issues by re-encoding images
- Always outputs one format `jpeg`, which keeps everything "normalized" and adds compression to images (mainly user uploads which might be big).
Having the changelog file is one more step to no vendor lock-in. It's also more easily searched through and in a standard format everyone is probably used to.
Just so you know, this was painful and I wanted nothing but death for myself throughout this whole process.
it isn't used and is only a way for others to potentially add activity to other peoples watched entries since user owning the watched entry is not validated on the endpoint.
Co-Authored-By: Dreddy <24421368+dredsen@users.noreply.github.com>
We don't use these columns and won't in the foreseeable future. Query speed seems be to be faster now that we aren't filtering for the extra deleted_at cols.
The font-style in the @font-face declaration was set to italic, but we use the font without using that style, which Safari is very strict about and wont match.
After deleting from your watched list through the poster, we didn't have any real indication to the user that this poster is for a deleted entry (other than the notification and removing the watched status from poster).
Now we grayscale and blur the poster slightly so it's more obvious that it is a deleted entry and won't be there next time you refresh.
Fixing watcharr import from watcharr export not importing users games.
Also works if user edits the table in import/process to change the type of something to a game (and multi results works too).
Added warning message if user tries importing a watcharr export that has games when `!serverFeatures.games`
Instead of completely removing it, I've added it back so third party scripts can migrate to the new property 'tmdbId'.
I realised I don't want to break any ones experience, this should allow for a painfree path to migration.
and ask for feedback if anyone actually uses this or prefers it off.
Incase people do actually find this setting useful, I'm leaving it intact and not creating a db migration to drop it yet until I hear any feedback.. otherwise I'll just delete it in one of the updates after 3.0.
Remove WatchedList component and create PosterLists directly on watched list and other users list pages.
Get Watched endpoints now return Media with watched inside them, same structure as search, etc. This makes the client logic easier and means we can always expect the same data response no matter how we request data.
Fix race cond in paginatedLoader & abort previous request inside reset func.
using derived to make a web request = slap on hand
and it was causing a bug where it would request the season twice after selecting another tv series from the similar list
Use the global blocks everywhere without having an argument.
Simpler using this everywhere instead of mix and matching + it will work when we have styles underneath so we dont have to keep adding global tag in each selector inside a global tag
use media in content pages, remove canvas from dom after img loaded in poster, fix filter menu buttons active style, view trailer btn is a component now, show justwatch attribution (didnt realise we had to until i saw the api docs to check providers data), no longer need to use copier for detail responses, move and make tranformproviders more resilient
I think it may be less confusing this way to users, since on the main multi page there is only the trending filter, so when they change the content filter it may not be obvious that more options are added, this way it is disabled until there are options that do something for the type of content selected.
adding games back later, got the new page working 1000x better for movies, tv and people (new!).
Some slight refactoring to other stuff I touched when getting the discover package up and running.
- Moved main scss files to src/styles.
- Instead of prepending all our global styles in svelte.config.js, we now only prepend our sass logic that doesn't build to css, which reduces the output css massively by avoiding duplicative imports. Our norm.scss is now imported in the root +layout file.
- Update sass package
- Renamed mixins and vars scss files to start with an underscore, which indicates they are partial files
I don't want this api to become a confusing behemoth so lets use full words where it makes sense.
'p' and 'l' also didn't fit in with our other query params that are already just the full word like 'type', etc.
Because the UI currently relies on this information for displaying the Last Watched extra detail for posters.
At some point, it'd likely be best that that logic is migrated to the backend, but for now doesn't really matter.
The query works as intended now (i think), gonna test it more later.
Not sure if performance has improved much, but without adjusting how our data looks I'm not sure how it could be solved. Going to worry about this specific sorts performance later though if it arises as an issue (its only a few ms more in my dev env on 1000 watched items, testing on beta site will give me a better idea since it has a lot more records).
Likely will never hit a case where the frontend will need this, but added anyways incase anyone making third party scripts want this functionality in the future
Now that we have everything encapsulated in Services, we can move the db parameters of each function into the service struct itself which:
1. Simplified calling and reduces us passing around the db in random funcs that just pass it to a service func
2. probably other stuff
3. looks nicer now
Easier to use this method so we can simply pass a pointer of our var in and let it do everything for us, relieves us of our manual type assertion duty everywhere we get from cache.
instead of separating both, should be easier to work with this way and enable it to work for search results without complex mapping etc to find related watched entries
This fixes firefox mobile.
Chromium on mobile stops the page from scrolling with a grace area while dragging the stars, but firefox doesn't do this, which breaks the (if scrolled dont save logic), so added the 10px grace into logic.
Future fix could be to stop the scrolling to mimic chromium behaviour for firefox mobile too, but that sound hard. Maybe firefox can fix this.
Just had an epiphany that it'd be better to return all results in this case, the frontend still sorts for best matches to be shown first, but then we keep all other options incase the users import data had a slight typo that matched other content etc.
* StarRating: Ignore star presses if scroll position changes from start to end of click
This should help us avoid accidental clicks of stars being saved when the user is just trying to scroll down the page.
* StarRating: Make scrollLocAtStart a normal variable
doesnt need to be $state
* feat(theme): add system preference handling to theme configuration
* Moved theme logic to new file, renamed vars, move system theme btn to top
- Moved `system` theme button to top (since its default).
- Moved theme logic to new `theme.ts` file & renamed some variables.
- Store: Revert change that sets updateStore=true when rehydrating theme (not necessary since we update store manually)
---------
Co-authored-by: IRHM <37304121+IRHM@users.noreply.github.com>
Makes the IMDb importer more robust by identifying more media types like Direct-to-Video movies, TV Mini Series and more which are all not regconized and thus skipped by the current importer.
It also makes a tiny UI change by adding the year of the imported movie to the "Multiple Results Found" dialog, which makes identifying the actually imported movie more easy and should help to reduce mismatches.
* FaceMenu: Add about modal
added modal with about info to FaceMenu bottom.
added 4 new SVG icons.
* FaceMenu: npm format
* FaceMenu: refactor about modal
- moved about modal into its own file
- minor fixes
* AboutModal: Add text to gh/site links, use Modal title prop, add attribution file link
, added a hover effect to all links in the modal and removed the margin on h5.
Also updated the top paragraph.
* AboutModal: Remove unused style
* Menu: Use color variables
---------
Co-authored-by: IRHM <37304121+IRHM@users.noreply.github.com>
* feat: improved overall look of the series season sidebar
* SeasonsList: Responsivity fixes
- Fix responsivity for seasons when names are very long (eg on shows that have custom season names)
- Increase status icon size
- Create color variables for season episodes text for resuability and to fix bug causing z index rendering issues with opacity usage.
* SeasonsList: checkSeasonStatus: Improve log
* SeasonsList: Remove $inspect: Causing errors in console for some reason
* vars: Fix --text-color-accent for dark theme
---------
Co-authored-by: IRHM <37304121+IRHM@users.noreply.github.com>
* app layout: Fix search styling and other small issues
- return destroy func in onMount to remove event listeners
- Fix timeout var type
* search: Fix searchUsers call not waiting for debounce
Fixes issue with new `prepare` script that we added for sveltekit, would always error here since we don't have any dev dependencies in this step for the command to work.
Also made the comments for each section bigger for readability (makes it easier to scan for where sections are).
Created a new <Menu> component which is now used for all of our menus (the ones for the nav + the menu in AddToTagButton).
Looks better now, easier to use, not sure why I ever did the global style for it, that was dumb. oh wait no im smart, it was probably because it wasn't used for the complex stuff it is now anyways shulda refactored ages agU
So that we can use the setters for saving properties to localStorage after an update. $effect is not meant to be used for this, so using setters seemed like the best option, gives us a lot more control over behaviour.
This change caused an issue where the poster mouseLeave event would not fire if the poster element was moved as a result of the re-sort, so some stuff has been restructured and a new call added to check if mouse is no longer over the poster to manually unactivate it.
this was wow many time wasted trying to figure this out but at least its a one time waste i hoppe.
Removed the games filter auto removal thing in filt() because it's not _really_ necessary. We have added additional UX stuff around this since, so if this rare case ever does occur, the user has easy ways around it.
- Refactored the newest/oldest sorts into one function used for both: newestOldestSort()
- Fixed an issue in the sort where an infinite loop could be caused when A & B both have no release date (added new case to resolve this).
Now using query parameters for the search queries (q).
Don't think theres a way to get slashes (/) working in the url without putting the whole query in a query param rather than the path param.
Think this is proper REST too prob
encountered a bug where doing a search while last was loading could infinitely keep loading next pages because curPage got higher than maxContentPage.
Corrected the logic to check for curPage bigger OR equal to max page, rather than only checking equal.
* person: show message when no credits to show
also hides filters when no credits, since they don't do anything in that case.
* person: remove unused css selector
- Removed min-width so improve responsivity for mobile (overflows).
- Removed unused styles (margin-top/bottom that were overridden in .container).
- Add max-width to match PosterList.
- Remove .container and add styles to .filters (combined them).
- Now makes the out file after the request, that way we ensure the request succeeds before creating the file.
- Added logging to every case, should make debugging easier in the future.
* Poster: Fix focus loss shrink issue
* PosterRating: Only add extra padding when is-minimal
So we don't alter the spacing when this component is used on an actual posters
.small-scrollbar is used on poster rating/status lists, but wasn't working because we also have the `scrollbar-width` property set, so now if the browser supports the webkit scrollbar styling, we will prefer that over scrollbar-width.
Don't know if this will break safari or whatever but hell if ima download that.
firefox scrollbar looks nice and this will let us keep using scrollbar-width: small wherever we want for that sweet smol bar action in ff
The inner container is not helpful for highlighting when tabbing through posters. The title of poster can still be used to enter the content via keyboard, the inner container did the same thing so was redundant and only added an extra click for any navigating via keyboard.
more control = need to be able to move it in js.
Still supports using ::before, so not all menus need updating and can stay simple, just the menus needing more control can start using an actual element for the arrow.
Currently will only shift elements back into view if out of bounds on the left.
Not necessary at the moment to support oob on other sides, or support resizing to fit. Maybe in the future when it's used more.
* test-pr.yml: Add format_check_go job
* separate test-pr into two files for client and server
so we can set the `paths` property and make the jobs only run when changes are detected for the client or server
* test breaking formatting
* correct formatting
* test-pr-server.yml: uncomment yml path
test has succeeded
We now wait for the save request to complete before unfocusing the stars, which avoids the jitter where it snaps back to actual rating before snapping to new rating when it finally saves
Is smaller when the media query makes the letter-spacing smaller. If i need to change this again, might be better to get it dynamically, but on component load and window resize instead of in each func call?
- Moved ExtraDetails (from Poster and GamePoster) to its own component for reuse, also no longer one line.
- Consolodated ExtraDetails and ExtraDetailsGame types into one type: PosterExtraDetails.
- Created Rating helpers lib. Contains: toShowableRating() and toWhichThumb()
- Fix extra detail dates not listing for games on search page
Instead of trying to center the rating text element ourselves by using its width/2, we can just simply rely on the tranlateX -50% style instead of removing it.
Seems to actually be accurate for what we need, I think we should just use float64 instead of importing a library for decimal values (if it continues working and i find no more issues)
Because of a bug with mouseleave tirggering when a star is clicked directly and browser focused at same time.
Also renamed handleStarHoverEnd->handleRatingHoverEnd since its now on the rating wrap element instead of a star element
Most of the client work is done:
- Added new RatingSystem and RatingStep settings
- Rating component now supports all systems and steps (minus thumbs)
Thumbs and server work for saving user setting and then testing! yupee
* Save requested season number in `LastViewedSeason` property
When season details are requested and a watchedId is passed as a query parameter, the requested season number is now saved in the watched entries `LastViewedSeason` property.
* SeasonsList: Restore activeSeason and update state after request with new lastViewedSeason value
* get season details route: add extra log for else case where no watchedId is found
Makes it easier when accessing the vite dev server from outside the local machine, instead of making me change the variable to my machines local ip all the time
* wip
* wip
* wip
* wip (also update go version)
* wip
* wip
* wip looks like its working
* increase job done time before deletion
30m seems more reasonable?
When a search request is running, and the query is changed, the previous request cancellation would hide the loader just after the new request started loading, resulting in the loader being hidden for the duration of the request being completed. Now the loader will only hide if the request errors, not for cancellations too which was causing this issue
* Initial implementation of ryot import process
* Bug fixes for movie imports and show ratings
* Cleanup
* Added Ryot's logo to import button
* Ryot import now supports the DROPPED flag for shows
* Formatted the code and added restrictions for tv shows and movies only
* Better units
* Prettier format
* Fix type errors, change stat styling to push value down
---------
Co-authored-by: IRHM <37304121+IRHM@users.noreply.github.com>
Has always been set as HOLD from frontend apparently, never used this value before on server so must've missed it (until now, i wasted a lot of time ;().
We weren't ensuring that the whole watched season object was set to hookResponse.WatchedSeason first, so they client wouldn't get the WatchedSeason `id` (so couldn't update the season).
* Support emby branding
Swap out jellyfin branding for emby when USE_EMBY is enabled.
* Server: Change jellyfin host setting text to emby when USE_EMBY enabled
basically buddy, if you search for something and filter for 'movies' (for example), then you change the search to something else, but no movies come up in the results, the 'movies' filter would hide, but still be active. That was confusing behavour, so now the button 'movies' in this case will always stay visible, if it's the active filter.
* Search: Add filters (for content type), remove terrible result sort, dynamic page title
* Search: Better responsiveness for filters
Moving margin to wrapper and adding to right makes it wrap sooner.
* Search: Even better responsiveness for filters
On smaller screens, changes flex-flow to column and centers buttons
to avoid thought changes being lost if the server fails when saving.
Also stopped saving changed on blur of textarea, now only saves when close modal is clicked.
* Country support for watch providers (#1, not functional)
* frontend dropdowns now actually read and write the correct setting
* user country setting now respects the server side default when creating a new user
* watch providers correctly show based on country, but changing the coutnry requires restarting the container to take effect
* flushing cache when updating user settings
* non functional, initial support for getting all the countries of which tmdb has streaming providers for to let users pick one
* users get shown a list of country codes to pick from and the selection gets saved and used, but the dropdown menu doesn't allow for scrolling
* limited dropdown height and auto scroll to the letter the user hits
* simplified auto scroll code
* the dropdown to choose countries now shows their full english name
* server/user region improvements
* DropDown: remove console log
used to test
* DropDown: Add keypress event listener on main div
instead of document body, so only triggered when key pressed whilst focused on dropdown.
---------
Co-authored-by: Stig <stig.narnia@gmail.com>
Co-authored-by: IRHM <37304121+IRHM@users.noreply.github.com>
* Issue #130
* Watcharr import: support activity import and fix ImportedList data
Also added padding to bottom of import page
---------
Co-authored-by: John Stephani <me@johnstephani.com>
Co-authored-by: IRHM <37304121+IRHM@users.noreply.github.com>
fetches data again, because I'm too lazy to make it work locally. Also don't think it's that crucial just for an admin page to make it super duper deliciouso at the el momento
So we can only apply then when the PosterList is in wrapping mode.
Added default min-width to posters of 170px.
This fixes posters on other pages, where they would be super small.
We now have two search bars in the markup to make this easily possible. When the size of the main input becomes too small to see the placeholder, we hide it and show another search bar below the main nav content.
Small range where we have a dynamic size to hopefully work better on a bigger range of devices. Can't go too big or too small otherwise the posters can become ugly and unusable.
Works well now with all the preset device sizes in my browser.
<!-- It's harder to track bugs when multiple are reported in one issue. If you have more than one (unrelated) bugs to report, please make one issue per bug. -->
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Platform (please complete the following information):**
<!-- Feature requests can be hard to track when two or more unrelated ideas are included in one issue. Please make a new issue for each idea (make as many as you need to). -->
**Idea Overview**
A quick overview of the idea you are proposing.
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
about: Help us with our documentation. Is something important missing?
title: ""
labels: documentation
assignees: IRHM
---
<!-- Did you know: You can click `Edit this page` at the bottom of any page on the docs to propose exact changes? If this doesn't apply to you, continue below and fill out the issue. -->
**What is missing or needs updating on the documentation site?**
Please describe in detail what is missing or needs updating on the documentation site.
**(optional) How would you write/update this doc?**
<!-- Make sure your code is formatted by running `npm run format` or using prettier manually. -->
<!-- AI Disclosure: <If you used AI to write the code, please disclose it by uncommenting this line and describing the usage. If AI wrote any of the code, do you fully understand it?> -->
### Changes made
<!-- Describe changes made here. If changes are visual a screenshot could be useful! -->
We haven't rebuilt the wheel from scratch, here are the tools that have helped this project come to fruition.
(I am creating this file a bit late, some tools may be missing, hopefully over time I can get everything listed here).
## Web Client
Look at our [package.json](./package.json) for the packages we directly use.
- [Ionicons](https://ionic.io/ionicons) When looking for high quality icons, I go here first. Most of the icons in Watcharr are from here.
- [Wikimedia Commons](https://commons.wikimedia.org) For [Streaming provider icons](https://commons.wikimedia.org/wiki/Category:SVG_logos_of_video_streaming_services).
- [Penpot](https://github.com/penpot/penpot) For initial UI design and creating the logo.
- [Google Fonts](https://fonts.google.com/) For custom fonts and for a few icons too. Don't worry though, fonts/icons are included in the Watcharr download, there are **no** requests made to google.
## Server
Look at our [go.mod](./server/go.mod) for the packages we use.
@@ -4,8 +4,14 @@ First of all, thank you for looking into contributing! 🫡
Feel free to contribute in any way: 🐞 bug reports, 💡 ideas, 🥖 new features etc - everything is welcome!
For big PRs (lots of changes/big change in the way something works), if you'd like, it can be discussed first in an issue (dont want to waste anyones time!).
Big pull requests (anything more than a few lines) should be discussed first in an issue (dont want to waste anyones time!).
## Project Board
We have a [board to organize new features and bug fixes](https://github.com/orgs/sbondCo/projects/9/views/2) to be worked on. If you see something you'd like to work on, just ask in the issue and it can be assigned to you. Even if it isn't set for the next milestone already, it can be.
## AI
If you use AI, please disclose the usage in your pull request.
Fully understanding any code that is submitted is a must because someone's gotta understand it!
A basic top-level view of the features included in Watcharr.
When the word `watched` is used, assume it can be `played` for games too.
**NOTE:** Have a look at when this document was last updated, it may have missing features. This document was made years after starting the project, so I have no doubt I've missed some stuff, this is a good overview anyways.
- Watched List
- Supported Content:
- Movies
- TV Shows / Anime
- Seasons
- Episodes
- Games
- Filtering
- Sorting
- Pinning
- Thoughts (for writing a review, etc)
- Activity (detailed list of modifications made to each watched item)
- Importing from other services
- Content detail pages
- Basic overview
- Watch trailer
- Available streaming providers in your region
- Cast
- Similar content
- List of all seasons and their episodes (for tv shows).
- Person detail pages
- Basic overview
- All credits (movies & tv they appear in or worked on)
- Searching for media
- Inline filters (ex: `y:2008` to get media released in 2008)
- Custom tags
- Discovery page
- Following other users
- Simple user stats (movies watched, time spent watching, etc)
- User Settings
- Dark & Light themes
- Privacy
- Hide Spoilers
- Rating System
- Out of 5
- Out of 10
- Out of 100
- Rating Step
- And more generic settings..
- Server dashboard
- Basic stats
- Configuration editing
- User management (including permissions)
- Jellyfin Integration
- Auth
- 'Play On Jellyfin' buttons
- Plex Integration
- Trusted Header Authentication (for auth via proxy)
- Basic Sonarr & Radarr integration
- Let users Request content (users can be given an auto approve permission)
@@ -16,36 +16,50 @@ With [some extra configuration](https://watcharr.app/docs/server_config/game-sup
I am built with Go and Svelte(Kit).
Feel free to abuse this demo instance (nicely), which runs on the latest `dev` build (there may be bugs, as new features are tested on here too): [https://beta.watcharr.app/](https://beta.watcharr.app/)
### Demo
[Track Progress Until Next Version](https://github.com/orgs/sbondCo/projects/9/views/3)
Feel free to abuse this demo instance (nicely). It runs on the latest `dev` build so there may be bugs, as new features are tested on here too. The demo is a worst-case scenario for speed (which is why I like it as a testing ground), if you host it yourself the app will be snappy.
**NOTE:** There is no demo account, just type in a random username/password (smashing hand into keyboard is supported), then click `Not a user?` at the bottom and a `Sign Up` button will appear.
### Track new features
Most patches are tracked through [our project board](https://github.com/orgs/sbondCo/projects/9/views/3), though I am very unorganised so expect surprise updates (or don't, if you like surprises)!
You can also [view a list of all current features](FEATURES.md).
@@ -53,8 +67,28 @@ Feel free to abuse this demo instance (nicely), which runs on the latest `dev` b
[Checkout our documentation](https://watcharr.app/docs/category/installation) for an up to date guide on setup! If you hate manuals, but love docker, this [docker-compose.yml](./docker-compose.yml) file is your friend.
# Community Made Tools
Third-party tools made by the community for enhancing your Watcharr experience!
- [Kodi Plugin](https://github.com/airdogvan/watcharr_kodi) by [airdogvan](https://github.com/airdogvan) for automatically tracking your watched shows/movies.
Thanks to anyone that has made a script or tool for Watcharr. Feel free to add your own to the list if you have one!
**Note:** I cannot provide any assurances for these tools or stay on top of them (code review, etc), if you have any problems please open an issue in the project for the tool so that they can stay organized.
# Getting Help
If something isn't working for you or you are stuck, [creating an issue](https://github.com/sbondCo/Watcharr/issues/new) is the best way to get help! Every type of issue is accepted, so don't be afraid to ask anything!
You can also [join our space on Matrix](https://matrix.to/#/#watcharr:matrix.org) for support.
I'll do my best to reply!
# License
This project is licensed under the GPLv3 license. You should see the [LICENSE](LICENSE) file located in the root folder of this project for the full license text, if not, see <https://www.gnu.org/licenses/>.
# Contributing
Please continue to our [contributing guide](CONTRIBUTING.md).
**Please do not report security vulnerabilities through public GitHub issues.**
You can reach out directly to [@irhm:matrix.org](https://matrix.to/#/@irhm:matrix.org) on matrix to discuss the vulnerability or you may [draft a new security advisory on this repository](https://github.com/sbondCo/Watcharr/security/advisories/new).
You may consider a backup of your server before starting any import. They are not easily reversible, though we do our best to ensure they are accurate and bug free!
:::
1. Export your list from MyAnimeList at: https://myanimelist.net/panel.php?go=export

2. Save the export anywhere and extract it to get your export `.xml` file.
You may consider a backup of your server before starting any import. They are not easily reversible, though we do our best to ensure they are accurate and bug free!
:::
The text file (.txt) import is of an arbitrary format (the one I used for years before creating Watcharr).
Hopefully it is useful for others with similar files or in scenarios where its the easiest to generate for an import (though if possible, when generating a backup from another service data manually, matching a Watcharr export would enable keeping more data).
## Format
Each line is a new entry. The name of the content (show/movie) must be provided. Doesn't support specifying if name is for a show or movie, the importer will only automatically match on full search matches, if there are multiple results, you will be asked to pick the correct one.
Optionally provide:
- The year in brackets (eg: `(1983)`)
- A rating (out of 10) in square brackets (eg: `[4]` or `[6.9]`)
You may consider a backup of your server before starting any import. They are not easily reversible, though we do our best to ensure they are accurate and bug free!
:::
**Note:** Your Trakt profile must be public _during_ this process. You are free to private it again once it completes.
1. Provide your Trakt username in the text box.
2. (Optional) [Provide your own api key](#optional-api-key).
3. Press `Start Import`.
This will be a long process, possibly a couple hours depending on how large of a Trakt history you have. If you think it has frozen or isn't working, try checking your server logs to see if it is doing anything.
### (Optional) API Key
This step is optional because Watcharr comes built in with its own API Key that it can use for your import, however, if you encounter any issues where imports cannot start or keep failing and you see any `403` errors in your server logs, providing your own key may fix the problem.
#### Getting an API Key
1. [Visit this link to create a new Trakt API App](https://trakt.tv/oauth/applications/new).
2. Fill out all required fields (`Name` and `Redirect uri`) with any random data.
1. You can set the `Redirect uri` to any value the input accepts since we don't use it (eg: `http://localhost`)
3. Click `Save App`.
4. You should now be redirected to your new app. Copy the `Client ID` into the `API Key` textbox in Watcharr.
You may consider a backup of your server before starting any import. They are not easily reversible, though we do our best to ensure they are accurate and bug free!
:::
:::warning May not be what you want
Watcharr import/export is a feature intended for end users. If you are the server admin, it is recommended that you copy your server files directly to any new server you are creating (it'll be much faster and easier). [See backup guide](/docs/server_config/backup).
:::
1. Provide the Watcharr export file (that you generated from your profile page).
2. Review the import table, if everything looks good, start the import.
description: Building from source for developing upon Watcharr.
---
# For Development
This guide will help you setup Watcharr for development in your local environment.
## Setup
This section assumes you will be forking the repo on Github, of course you can alter this section to work with your workflow, but if you intend to create a pull request with your work, it may be difficult if you're not also using Github (I don't know :()).
1. Fork the repository
On GitHub you can fork the repository with the 'Fork' button at the top.

2. Get the code by cloning your fork (edit the command and replace `<your username>` with your GitHub username or replace the whole url with the correct one pointing to your fork).
You only need to do this once after pulling the codebase for the first time, and again every time the dependencies are changed/updated.
1. Install frontend dependencies (in the project root folder)
```
npm i
```
2. Install server dependencies (in the `server` folder). Go does this automatically if you try starting the server and it notices you don't have them.
```
go get .
```
## Running The Code
To run the code, you will need to open up two terminals, one for the frontend and the other for the backend.
We have `Makefile`s for the frontend and server, so you can simply call `make` in each directory. Most Linux distros (as far as I know) include `make`, so you don't need to install anything. If you don't have `make`, you can either install it (lookup how to get "GNU Make" for your specific OS) OR you can just look inside the Makefiles and manually run the first command in each.
1. Run the frontend (first terminal, in the project root folder)
```bash
make
```
2. Run the server (second terminal, in the `server` folder)
```bash
make
```
**Note:** If you're using Windows, running the server can be a little more complicated. You can follow this: https://github.com/sbondCo/Watcharr/discussions/430#discussioncomment-8894110 which amounts to these steps (the first 3 steps only need to be done once):
1. Set CGO_ENABLED environment variable with go
```
go env -w CGO_ENABLED=1
```
2. Install `gcc` (if you don't already have it installed) from https://jmeubank.github.io/tdm-gcc/ (found from this answer on stackoverflow: https://stackoverflow.com/a/43588236).
3. Install server dependencies again with `go get .` in the `server` folder.
4. Manually run the server, setting the MODE environment variable in powershell (from the `server` folder)
```
cmd /V /C "set MODE=DEV&& go run ."
```
3. Visit [http://localhost:5173/](http://localhost:5173/) and setup Watcharr.
Watcharr cannot handle backing up for you, but its simple structure should make it easy to slide it into your existing backup routine.
Once you have created your first backup, it's recommended that you try restoring from that backup to make sure everything is correct and will work in case you need to restore from it in the future.
:::danger Shutdown your server!
Always shutdown Watcharr before backing up its data, otherwise you run the risk of corrupting files (mainly your database).
:::
## Simple Steps
:::success Recommended
This is the recommended way to backup.
:::
Here are the steps that are run daily for the `beta.watcharr.app` instance.
1. Shutdown Watcharr.
2. Copy and backup the entire `data` folder (default location is `./data`, backup whichever folder your server is configured to store its data in).
3. Start Watcharr.
I call these the simple steps because they simply backup your entire server, if you ever need to restore your server, it will start up from its exact state at backup.
## Advanced Steps
:::danger Discouraged
Backing up this way is discouraged because new important files could be added later and missed.
:::
If you don't care about the warning not to backup this way, here are the "important" files that you can single out for backup:
-`watcharr.db` & `watcharr.db-wal` Your database, holds all users, their watchlists, etc.
-`watcharr.json` Server config.
-`img/up` Profile picture uploads.
-`img/games` Game posters (not exactly important, but scenarios in which this folder is not backed up have not been tested, only relevant for servers with game support enabled).
description: All environment variables you can use to start your server in a specific way.
---
# Environment Variables
Currently there is only one, and maybe it will stay that way forever (because the admin interface can handle most settings). A very lonely page right now ;(.
## `WATCHARR_DATA`
Make Watcharr use a custom directory for all of its data.
Game support in Watcharr, currently, must be enabled by you.
This involves setting up a Twitch developer account (phone number needed for 2FA which is required) and entering application credentials into Watcharr, that can then be used for looking up game info via IGDB.
P.S. These steps are stolen from [igdb api docs](https://api-docs.igdb.com/#account-creation), I've tried to make it easier to follow with screenshots.
description: Getting admin privileges for your account without already having access to an account with admin.
---
# Restoring Admin Priviliges
This guide will help you restore/give admin access to any account without needing an account with admin. If you ever accidentally remove your permissions, this is the easiest way to get them back.
All you will need is access to the `watcharr.log` file.
## Steps
1. Login with the account you'd like to give admin to.
2. Navigate to the `/request_admin` page manually (ex: `127.0.0.1:3080/request_admin`) and click the `request` button.

3. Check your `watcharr.log` file (or simply check `docker compose logs` if using docker compose) and look for the generated admin token (highlighted in the image below).

4. Enter the code from the log (you should have been taken here after clicking the request button in step 2).
description="Description will go into a meta tag in <head />"
>
<HomepageHeader/>
<main>
<HomepageFeatures/>
<HomepageTwoColFeats/>
</main>
</Layout>
);
const{siteConfig}=useDocusaurusContext();
return(
<Layout
title={`${siteConfig.title}`}
description="Description will go into a meta tag in <head />"
>
<HomepageHeader/>
<main>
<HomepageFeatures/>
<HomepageTwoColFeats/>
</main>
</Layout>
);
}
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.