[scrobbles] Blacken files and add local dev static
This commit is contained in:
@ -139,7 +139,6 @@ def build_book_map(rows) -> dict:
|
||||
book_id_map = {}
|
||||
|
||||
for book_row in rows:
|
||||
|
||||
if book_row[KoReaderBookColumn.TITLE.value] in BOOKS_TITLES_TO_IGNORE:
|
||||
logger.info(
|
||||
"[build_book_map] Ignoring book title that is likely garbage",
|
||||
@ -147,9 +146,7 @@ def build_book_map(rows) -> dict:
|
||||
)
|
||||
continue
|
||||
book = Book.objects.filter(
|
||||
koreader_data_by_hash__icontains=book_row[
|
||||
KoReaderBookColumn.MD5.value
|
||||
]
|
||||
koreader_data_by_hash__icontains=book_row[KoReaderBookColumn.MD5.value]
|
||||
).first()
|
||||
|
||||
if not book:
|
||||
@ -203,15 +200,11 @@ def build_page_data(page_rows: list, book_map: dict, user_tz=None) -> dict:
|
||||
"end_ts": start_ts + duration,
|
||||
}
|
||||
if book_ids_not_found:
|
||||
logger.info(
|
||||
f"Found pages for books not in file: {set(book_ids_not_found)}"
|
||||
)
|
||||
logger.info(f"Found pages for books not in file: {set(book_ids_not_found)}")
|
||||
return book_map
|
||||
|
||||
|
||||
def build_scrobbles_from_book_map(
|
||||
book_map: dict, user: "User"
|
||||
) -> list["Scrobble"]:
|
||||
def build_scrobbles_from_book_map(book_map: dict, user: "User") -> list["Scrobble"]:
|
||||
Scrobble = apps.get_model("scrobbles", "Scrobble")
|
||||
|
||||
scrobbles_to_create = []
|
||||
@ -241,9 +234,9 @@ def build_scrobbles_from_book_map(
|
||||
|
||||
seconds_from_last_page = 0
|
||||
if prev_page_stats:
|
||||
seconds_from_last_page = stats.get(
|
||||
"end_ts"
|
||||
) - prev_page_stats.get("start_ts")
|
||||
seconds_from_last_page = stats.get("end_ts") - prev_page_stats.get(
|
||||
"start_ts"
|
||||
)
|
||||
|
||||
playback_position_seconds = playback_position_seconds + stats.get(
|
||||
"duration"
|
||||
@ -252,9 +245,7 @@ def build_scrobbles_from_book_map(
|
||||
end_of_reading = pages_processed == total_pages_read
|
||||
big_jump_to_this_page = (cur_page_number - last_page_number) > 10
|
||||
is_session_gap = seconds_from_last_page > SESSION_GAP_SECONDS
|
||||
if (
|
||||
is_session_gap and not big_jump_to_this_page
|
||||
) or end_of_reading:
|
||||
if (is_session_gap and not big_jump_to_this_page) or end_of_reading:
|
||||
should_create_scrobble = True
|
||||
|
||||
if should_create_scrobble:
|
||||
@ -378,9 +369,7 @@ def process_koreader_sqlite_file(file_path, user_id) -> list:
|
||||
return new_scrobbles
|
||||
|
||||
book_map = build_page_data(
|
||||
cur.execute(
|
||||
"SELECT * from page_stat_data ORDER BY id_book, start_time"
|
||||
),
|
||||
cur.execute("SELECT * from page_stat_data ORDER BY id_book, start_time"),
|
||||
book_map,
|
||||
tz,
|
||||
)
|
||||
|
||||
@ -58,9 +58,7 @@ logger = logging.getLogger(__name__)
|
||||
User = get_user_model()
|
||||
BNULL = {"blank": True, "null": True}
|
||||
|
||||
POINTS_FOR_MOVEMENT_HISTORY = int(
|
||||
getattr(settings, "POINTS_FOR_MOVEMENT_HISTORY", 3)
|
||||
)
|
||||
POINTS_FOR_MOVEMENT_HISTORY = int(getattr(settings, "POINTS_FOR_MOVEMENT_HISTORY", 3))
|
||||
|
||||
|
||||
class BaseFileImportMixin(TimeStampedModel):
|
||||
@ -96,7 +94,6 @@ class BaseFileImportMixin(TimeStampedModel):
|
||||
from scrobbles.models import Scrobble
|
||||
|
||||
if not self.process_log:
|
||||
|
||||
logger.warning("No lines in process log found to undo")
|
||||
return
|
||||
|
||||
@ -104,9 +101,7 @@ class BaseFileImportMixin(TimeStampedModel):
|
||||
scrobble_id = line.split("\t")[0]
|
||||
scrobble = Scrobble.objects.filter(id=scrobble_id).first()
|
||||
if not scrobble:
|
||||
logger.warning(
|
||||
f"Could not find scrobble {scrobble_id} to undo"
|
||||
)
|
||||
logger.warning(f"Could not find scrobble {scrobble_id} to undo")
|
||||
continue
|
||||
logger.info(f"Removing scrobble {scrobble_id}")
|
||||
if not dryrun:
|
||||
@ -149,9 +144,7 @@ class BaseFileImportMixin(TimeStampedModel):
|
||||
return
|
||||
|
||||
for count, scrobble in enumerate(scrobbles):
|
||||
scrobble_str = (
|
||||
f"{scrobble.id}\t{scrobble.timestamp}\t{scrobble.media_obj}"
|
||||
)
|
||||
scrobble_str = f"{scrobble.id}\t{scrobble.timestamp}\t{scrobble.media_obj}"
|
||||
log_line = f"{scrobble_str}"
|
||||
if count > 0:
|
||||
log_line = "\n" + log_line
|
||||
@ -173,9 +166,7 @@ class KoReaderImport(BaseFileImportMixin):
|
||||
return "KOReader"
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse(
|
||||
"scrobbles:koreader-import-detail", kwargs={"slug": self.uuid}
|
||||
)
|
||||
return reverse("scrobbles:koreader-import-detail", kwargs={"slug": self.uuid})
|
||||
|
||||
def get_path(instance, filename):
|
||||
extension = filename.split(".")[-1]
|
||||
@ -211,15 +202,11 @@ class KoReaderImport(BaseFileImportMixin):
|
||||
fix_profile_historic_timezones(self.user.profile)
|
||||
|
||||
if self.processed_finished and not force:
|
||||
logger.info(
|
||||
f"{self} already processed on {self.processed_finished}"
|
||||
)
|
||||
logger.info(f"{self} already processed on {self.processed_finished}")
|
||||
return
|
||||
|
||||
self.mark_started()
|
||||
scrobbles = process_koreader_sqlite_file(
|
||||
self.upload_file_path, self.user.id
|
||||
)
|
||||
scrobbles = process_koreader_sqlite_file(self.upload_file_path, self.user.id)
|
||||
self.record_log(scrobbles)
|
||||
self.mark_finished()
|
||||
|
||||
@ -233,9 +220,7 @@ class AudioScrobblerTSVImport(BaseFileImportMixin):
|
||||
return "AudiosScrobbler"
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse(
|
||||
"scrobbles:tsv-import-detail", kwargs={"slug": self.uuid}
|
||||
)
|
||||
return reverse("scrobbles:tsv-import-detail", kwargs={"slug": self.uuid})
|
||||
|
||||
def get_path(instance, filename):
|
||||
extension = filename.split(".")[-1]
|
||||
@ -259,16 +244,12 @@ class AudioScrobblerTSVImport(BaseFileImportMixin):
|
||||
fix_profile_historic_timezones(self.user.profile)
|
||||
|
||||
if self.processed_finished and not force:
|
||||
logger.info(
|
||||
f"{self} already processed on {self.processed_finished}"
|
||||
)
|
||||
logger.info(f"{self} already processed on {self.processed_finished}")
|
||||
return
|
||||
|
||||
self.mark_started()
|
||||
|
||||
scrobbles = import_audioscrobbler_tsv_file(
|
||||
self.upload_file_path, self.user.id
|
||||
)
|
||||
scrobbles = import_audioscrobbler_tsv_file(self.upload_file_path, self.user.id)
|
||||
self.record_log(scrobbles)
|
||||
self.mark_finished()
|
||||
|
||||
@ -282,9 +263,7 @@ class LastFmImport(BaseFileImportMixin):
|
||||
return "LastFM"
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse(
|
||||
"scrobbles:lastfm-import-detail", kwargs={"slug": self.uuid}
|
||||
)
|
||||
return reverse("scrobbles:lastfm-import-detail", kwargs={"slug": self.uuid})
|
||||
|
||||
def process(self, import_all=False):
|
||||
"""Import scrobbles found on LastFM"""
|
||||
@ -293,9 +272,7 @@ class LastFmImport(BaseFileImportMixin):
|
||||
fix_profile_historic_timezones(self.user.profile)
|
||||
|
||||
if self.processed_finished:
|
||||
logger.info(
|
||||
f"{self} already processed on {self.processed_finished}"
|
||||
)
|
||||
logger.info(f"{self} already processed on {self.processed_finished}")
|
||||
return
|
||||
|
||||
last_import = None
|
||||
@ -333,9 +310,7 @@ class RetroarchImport(BaseFileImportMixin):
|
||||
return "Retroarch"
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse(
|
||||
"scrobbles:retroarch-import-detail", kwargs={"slug": self.uuid}
|
||||
)
|
||||
return reverse("scrobbles:retroarch-import-detail", kwargs={"slug": self.uuid})
|
||||
|
||||
def process(self, import_all=False, force=False):
|
||||
"""Import scrobbles found on Retroarch"""
|
||||
@ -343,9 +318,7 @@ class RetroarchImport(BaseFileImportMixin):
|
||||
fix_profile_historic_timezones(self.user.profile)
|
||||
|
||||
if self.processed_finished and not force:
|
||||
logger.info(
|
||||
f"{self} already processed on {self.processed_finished}"
|
||||
)
|
||||
logger.info(f"{self} already processed on {self.processed_finished}")
|
||||
return
|
||||
|
||||
if force:
|
||||
@ -536,39 +509,25 @@ class Scrobble(TimeStampedModel):
|
||||
podcast_episode = models.ForeignKey(
|
||||
PodcastEpisode, on_delete=models.DO_NOTHING, **BNULL
|
||||
)
|
||||
sport_event = models.ForeignKey(
|
||||
SportEvent, on_delete=models.DO_NOTHING, **BNULL
|
||||
)
|
||||
sport_event = models.ForeignKey(SportEvent, on_delete=models.DO_NOTHING, **BNULL)
|
||||
book = models.ForeignKey(Book, on_delete=models.DO_NOTHING, **BNULL)
|
||||
paper = models.ForeignKey(Paper, on_delete=models.DO_NOTHING, **BNULL)
|
||||
video_game = models.ForeignKey(
|
||||
VideoGame, on_delete=models.DO_NOTHING, **BNULL
|
||||
)
|
||||
board_game = models.ForeignKey(
|
||||
BoardGame, on_delete=models.DO_NOTHING, **BNULL
|
||||
)
|
||||
geo_location = models.ForeignKey(
|
||||
GeoLocation, on_delete=models.DO_NOTHING, **BNULL
|
||||
)
|
||||
video_game = models.ForeignKey(VideoGame, on_delete=models.DO_NOTHING, **BNULL)
|
||||
board_game = models.ForeignKey(BoardGame, on_delete=models.DO_NOTHING, **BNULL)
|
||||
geo_location = models.ForeignKey(GeoLocation, on_delete=models.DO_NOTHING, **BNULL)
|
||||
beer = models.ForeignKey(Beer, on_delete=models.DO_NOTHING, **BNULL)
|
||||
puzzle = models.ForeignKey(Puzzle, on_delete=models.DO_NOTHING, **BNULL)
|
||||
food = models.ForeignKey(Food, on_delete=models.DO_NOTHING, **BNULL)
|
||||
trail = models.ForeignKey(Trail, on_delete=models.DO_NOTHING, **BNULL)
|
||||
task = models.ForeignKey(Task, on_delete=models.DO_NOTHING, **BNULL)
|
||||
web_page = models.ForeignKey(WebPage, on_delete=models.DO_NOTHING, **BNULL)
|
||||
life_event = models.ForeignKey(
|
||||
LifeEvent, on_delete=models.DO_NOTHING, **BNULL
|
||||
)
|
||||
life_event = models.ForeignKey(LifeEvent, on_delete=models.DO_NOTHING, **BNULL)
|
||||
mood = models.ForeignKey(Mood, on_delete=models.DO_NOTHING, **BNULL)
|
||||
brick_set = models.ForeignKey(
|
||||
BrickSet, on_delete=models.DO_NOTHING, **BNULL
|
||||
)
|
||||
brick_set = models.ForeignKey(BrickSet, on_delete=models.DO_NOTHING, **BNULL)
|
||||
media_type = models.CharField(
|
||||
max_length=14, choices=MediaType.choices, default=MediaType.VIDEO
|
||||
)
|
||||
user = models.ForeignKey(
|
||||
User, blank=True, null=True, on_delete=models.DO_NOTHING
|
||||
)
|
||||
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.DO_NOTHING)
|
||||
|
||||
# Time keeping
|
||||
timestamp = models.DateTimeField(**BNULL)
|
||||
@ -596,9 +555,7 @@ class Scrobble(TimeStampedModel):
|
||||
upload_to="scrobbles/videogame_save_data/", **BNULL
|
||||
)
|
||||
gpx_file = models.FileField(upload_to="scrobbles/gpx_file/", **BNULL)
|
||||
screenshot = models.ImageField(
|
||||
upload_to="scrobbles/videogame_screenshot/", **BNULL
|
||||
)
|
||||
screenshot = models.ImageField(upload_to="scrobbles/videogame_screenshot/", **BNULL)
|
||||
screenshot_small = ImageSpecField(
|
||||
source="screenshot",
|
||||
processors=[ResizeToFit(100, 100)],
|
||||
@ -614,6 +571,16 @@ class Scrobble(TimeStampedModel):
|
||||
long_play_seconds = models.BigIntegerField(**BNULL)
|
||||
long_play_complete = models.BooleanField(**BNULL)
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
models.Index(fields=["timestamp"]),
|
||||
models.Index(fields=["media_type"]),
|
||||
models.Index(fields=["source_id"]),
|
||||
models.Index(
|
||||
fields=["user", "in_progress", "played_to_completion", "is_paused"]
|
||||
),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def for_year(cls, user, year):
|
||||
return cls.objects.filter(timestamp__year=year, user=user).order_by(
|
||||
@ -679,9 +646,7 @@ class Scrobble(TimeStampedModel):
|
||||
from scrobbles.models import Scrobble
|
||||
|
||||
if self.logdata and self.logdata.serial_scrobble_id:
|
||||
return Scrobble.objects.filter(
|
||||
id=self.logdata.serial_scrobble_id
|
||||
).first()
|
||||
return Scrobble.objects.filter(id=self.logdata.serial_scrobble_id).first()
|
||||
|
||||
@property
|
||||
def finish_url(self) -> str:
|
||||
@ -703,8 +668,12 @@ class Scrobble(TimeStampedModel):
|
||||
if self.media_obj:
|
||||
self.media_type = self.MediaType(self.media_obj.__class__.__name__)
|
||||
|
||||
if (self.timestamp and self.stop_timestamp) and (not self.playback_position_seconds or self.playback_position_seconds <= 0):
|
||||
self.playback_position_seconds = (self.stop_timestamp - self.timestamp).seconds
|
||||
if (self.timestamp and self.stop_timestamp) and (
|
||||
not self.playback_position_seconds or self.playback_position_seconds <= 0
|
||||
):
|
||||
self.playback_position_seconds = (
|
||||
self.stop_timestamp - self.timestamp
|
||||
).seconds
|
||||
|
||||
return super(Scrobble, self).save(*args, **kwargs)
|
||||
|
||||
@ -715,9 +684,9 @@ class Scrobble(TimeStampedModel):
|
||||
return reverse("scrobbles:detail", kwargs={"uuid": self.uuid})
|
||||
|
||||
def push_to_archivebox(self):
|
||||
pushable_media = hasattr(
|
||||
self.media_obj, "push_to_archivebox"
|
||||
) and callable(self.media_obj.push_to_archivebox)
|
||||
pushable_media = hasattr(self.media_obj, "push_to_archivebox") and callable(
|
||||
self.media_obj.push_to_archivebox
|
||||
)
|
||||
|
||||
if pushable_media and self.user.profile.archivebox_url:
|
||||
try:
|
||||
@ -781,10 +750,7 @@ class Scrobble(TimeStampedModel):
|
||||
logger.info(f"Redirecting to {self.media_obj.url}")
|
||||
redirect_url = self.media_obj.url
|
||||
|
||||
if (
|
||||
self.media_type == self.MediaType.VIDEO
|
||||
and self.media_obj.youtube_id
|
||||
):
|
||||
if self.media_type == self.MediaType.VIDEO and self.media_obj.youtube_id:
|
||||
redirect_url = self.media_obj.youtube_link
|
||||
|
||||
return redirect_url
|
||||
@ -800,9 +766,7 @@ class Scrobble(TimeStampedModel):
|
||||
@property
|
||||
def local_stop_timestamp(self):
|
||||
if self.stop_timestamp:
|
||||
return timezone.localtime(
|
||||
self.stop_timestamp, timezone=self.tzinfo
|
||||
)
|
||||
return timezone.localtime(self.stop_timestamp, timezone=self.tzinfo)
|
||||
|
||||
@property
|
||||
def scrobble_media_key(self) -> str:
|
||||
@ -930,9 +894,7 @@ class Scrobble(TimeStampedModel):
|
||||
long_play_secs = 0
|
||||
if self.previous and not self.previous.long_play_complete:
|
||||
long_play_secs = self.previous.long_play_seconds or 0
|
||||
percent = int(
|
||||
((playback_seconds + long_play_secs) / run_time_secs) * 100
|
||||
)
|
||||
percent = int(((playback_seconds + long_play_secs) / run_time_secs) * 100)
|
||||
|
||||
return percent
|
||||
|
||||
@ -977,9 +939,7 @@ class Scrobble(TimeStampedModel):
|
||||
expected_end = self.timestamp + datetime.timedelta(
|
||||
seconds=self.media_obj.run_time_seconds
|
||||
)
|
||||
expected_end_padded = expected_end + datetime.timedelta(
|
||||
seconds=padding_seconds
|
||||
)
|
||||
expected_end_padded = expected_end + datetime.timedelta(seconds=padding_seconds)
|
||||
# Take our start time, add our media length and an extra 30 min (1800s) is it still in the future? keep going
|
||||
is_in_progress = expected_end_padded > pendulum.now()
|
||||
logger.info(
|
||||
@ -995,7 +955,10 @@ class Scrobble(TimeStampedModel):
|
||||
|
||||
@property
|
||||
def can_be_updated(self) -> bool:
|
||||
if self.media_obj.__class__.__name__ in LONG_PLAY_MEDIA.values() and self.source != "readcomicsonline.ru":
|
||||
if (
|
||||
self.media_obj.__class__.__name__ in LONG_PLAY_MEDIA.values()
|
||||
and self.source != "readcomicsonline.ru"
|
||||
):
|
||||
logger.info(
|
||||
"[scrobbling] cannot be updated, long play media",
|
||||
extra={
|
||||
@ -1039,11 +1002,9 @@ class Scrobble(TimeStampedModel):
|
||||
|
||||
@classmethod
|
||||
def by_date(cls, media_type: str = "Track"):
|
||||
cls.objects.filter(media_type=media_type).values(
|
||||
"timestamp__date"
|
||||
).annotate(count=models.Count("id")).values(
|
||||
"timestamp__date", "count"
|
||||
).order_by(
|
||||
cls.objects.filter(media_type=media_type).values("timestamp__date").annotate(
|
||||
count=models.Count("id")
|
||||
).values("timestamp__date", "count").order_by(
|
||||
"-count",
|
||||
)
|
||||
|
||||
@ -1150,7 +1111,10 @@ class Scrobble(TimeStampedModel):
|
||||
if existing_by_source_id:
|
||||
logger.info(
|
||||
"[create_or_update] found existing scrobble by source_id, updating",
|
||||
extra={"scrobble_id": existing_by_source_id.id, "source_id": source_id},
|
||||
extra={
|
||||
"scrobble_id": existing_by_source_id.id,
|
||||
"source_id": source_id,
|
||||
},
|
||||
)
|
||||
scrobble_data["playback_status"] = scrobble_data.pop("status", None)
|
||||
return existing_by_source_id.update(scrobble_data)
|
||||
@ -1172,9 +1136,7 @@ class Scrobble(TimeStampedModel):
|
||||
logger.warning(
|
||||
f"[create_or_update] geoloc requires create_or_update_location"
|
||||
)
|
||||
scrobble = cls.create_or_update_location(
|
||||
media, scrobble_data, user_id
|
||||
)
|
||||
scrobble = cls.create_or_update_location(media, scrobble_data, user_id)
|
||||
return scrobble
|
||||
|
||||
if not skip_in_progress_check or read_log_page:
|
||||
@ -1187,9 +1149,7 @@ class Scrobble(TimeStampedModel):
|
||||
"scrobble_data": scrobble_data,
|
||||
},
|
||||
)
|
||||
scrobble_data["playback_status"] = scrobble_data.pop(
|
||||
"status", None
|
||||
)
|
||||
scrobble_data["playback_status"] = scrobble_data.pop("status", None)
|
||||
# If it's marked as stopped, send it through our update mechanism, which will complete it
|
||||
if scrobble and (
|
||||
scrobble.can_be_updated
|
||||
@ -1207,7 +1167,7 @@ class Scrobble(TimeStampedModel):
|
||||
page_list.append(
|
||||
BookPageLogData(
|
||||
page_number=read_log_page,
|
||||
start_ts=int(timezone.now().timestamp())
|
||||
start_ts=int(timezone.now().timestamp()),
|
||||
)
|
||||
)
|
||||
scrobble.log["page_data"] = page_list
|
||||
@ -1220,7 +1180,14 @@ class Scrobble(TimeStampedModel):
|
||||
scrobble_data.pop("playback_status")
|
||||
|
||||
if read_log_page:
|
||||
scrobble_data["log"] = BookLogData(page_data=[BookPageLogData(page_number=read_log_page, start_ts=int(timezone.now().timestamp()))])
|
||||
scrobble_data["log"] = BookLogData(
|
||||
page_data=[
|
||||
BookPageLogData(
|
||||
page_number=read_log_page,
|
||||
start_ts=int(timezone.now().timestamp()),
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"[scrobbling] creating new scrobble",
|
||||
@ -1231,7 +1198,9 @@ class Scrobble(TimeStampedModel):
|
||||
"source": source,
|
||||
},
|
||||
)
|
||||
if mtype == cls.MediaType.FOOD and not scrobble_data.get("log", {}).get("calories", None):
|
||||
if mtype == cls.MediaType.FOOD and not scrobble_data.get("log", {}).get(
|
||||
"calories", None
|
||||
):
|
||||
if media.calories:
|
||||
scrobble_data["log"] = FoodLogData(calories=media.calories)
|
||||
|
||||
@ -1318,9 +1287,7 @@ class Scrobble(TimeStampedModel):
|
||||
if existing_locations := location.in_proximity(named=True):
|
||||
existing_location = existing_locations.first()
|
||||
ts = int(pendulum.now().timestamp())
|
||||
scrobble.log[
|
||||
ts
|
||||
] = f"Location {location.id} too close to this scrobble"
|
||||
scrobble.log[ts] = f"Location {location.id} too close to this scrobble"
|
||||
scrobble.save(update_fields=["log"])
|
||||
logger.info(
|
||||
f"[scrobbling] finished - found existing named location",
|
||||
@ -1499,9 +1466,7 @@ class Scrobble(TimeStampedModel):
|
||||
"""Returns true if our media is beyond our completion percent, unless
|
||||
our type is geolocation in which case we always return false
|
||||
"""
|
||||
beyond_completion = (
|
||||
self.percent_played >= self.media_obj.COMPLETION_PERCENT
|
||||
)
|
||||
beyond_completion = self.percent_played >= self.media_obj.COMPLETION_PERCENT
|
||||
|
||||
if self.media_type == "GeoLocation":
|
||||
logger.info(
|
||||
|
||||
@ -87,6 +87,7 @@ def mopidy_scrobble_media(post_data: dict, user_id: int) -> Scrobble:
|
||||
log = {
|
||||
"mopidy_source": post_data.get("mopidy_uri", "").split(":")[0],
|
||||
"raw_data": post_data,
|
||||
"album": post_data.get("album", ""),
|
||||
}
|
||||
except IndexError:
|
||||
pass
|
||||
@ -95,17 +96,14 @@ def mopidy_scrobble_media(post_data: dict, user_id: int) -> Scrobble:
|
||||
user_id,
|
||||
source="Mopidy",
|
||||
playback_position_seconds=int(
|
||||
post_data.get(MOPIDY_POST_KEYS.get("PLAYBACK_POSITION_TICKS"), 1)
|
||||
/ 1000
|
||||
post_data.get(MOPIDY_POST_KEYS.get("PLAYBACK_POSITION_TICKS"), 1) / 1000
|
||||
),
|
||||
status=post_data.get(MOPIDY_POST_KEYS.get("STATUS"), ""),
|
||||
log=log,
|
||||
)
|
||||
|
||||
|
||||
def jellyfin_scrobble_media(
|
||||
post_data: dict, user_id: int
|
||||
) -> Optional[Scrobble]:
|
||||
def jellyfin_scrobble_media(post_data: dict, user_id: int) -> Optional[Scrobble]:
|
||||
media_type = Scrobble.MediaType.VIDEO
|
||||
if post_data.pop("ItemType", "") in JELLYFIN_AUDIO_ITEM_TYPES:
|
||||
media_type = Scrobble.MediaType.TRACK
|
||||
@ -123,13 +121,12 @@ def jellyfin_scrobble_media(
|
||||
)
|
||||
return
|
||||
|
||||
timestamp = parse(
|
||||
post_data.get(JELLYFIN_POST_KEYS.get("TIMESTAMP"), "")
|
||||
).replace(tzinfo=pytz.utc)
|
||||
timestamp = parse(post_data.get(JELLYFIN_POST_KEYS.get("TIMESTAMP"), "")).replace(
|
||||
tzinfo=pytz.utc
|
||||
)
|
||||
|
||||
playback_position_seconds = int(
|
||||
post_data.get(JELLYFIN_POST_KEYS.get("PLAYBACK_POSITION_TICKS"), 1)
|
||||
/ 10000000
|
||||
post_data.get(JELLYFIN_POST_KEYS.get("PLAYBACK_POSITION_TICKS"), 1) / 10000000
|
||||
)
|
||||
if media_type == Scrobble.MediaType.VIDEO:
|
||||
imdb_id = post_data.get("Provider_imdb", "")
|
||||
@ -139,9 +136,7 @@ def jellyfin_scrobble_media(
|
||||
title=post_data.get("Name", ""),
|
||||
artist_name=post_data.get("Artist", ""),
|
||||
album_name=post_data.get("Album", ""),
|
||||
run_time_seconds=convert_to_seconds(
|
||||
post_data.get("RunTime", 900000)
|
||||
),
|
||||
run_time_seconds=convert_to_seconds(post_data.get("RunTime", 900000)),
|
||||
)
|
||||
# A hack because we don't worry about updating music ... we either finish it or we don't
|
||||
playback_position_seconds = 0
|
||||
@ -165,6 +160,7 @@ def jellyfin_scrobble_media(
|
||||
source_id=post_data.get(JELLYFIN_POST_KEYS.get("MEDIA_SOURCE_ID")),
|
||||
playback_position_seconds=playback_position_seconds,
|
||||
status=playback_status,
|
||||
log={"album": post_data.get("Album", "")},
|
||||
)
|
||||
|
||||
|
||||
@ -301,9 +297,7 @@ def manual_scrobble_book(
|
||||
if not page:
|
||||
page = 1
|
||||
|
||||
logger.info(
|
||||
"[scrobblers] Book page included in scrobble, should update!"
|
||||
)
|
||||
logger.info("[scrobblers] Book page included in scrobble, should update!")
|
||||
|
||||
source = READCOMICSONLINE_URL.replace("https://", "")
|
||||
|
||||
@ -420,9 +414,7 @@ def email_scrobble_board_game(
|
||||
if not location.name:
|
||||
location.name = location_dict.get("name")
|
||||
update_fields.append("name")
|
||||
geoloc = GeoLocation.objects.filter(
|
||||
title__icontains=location.name
|
||||
).first()
|
||||
geoloc = GeoLocation.objects.filter(title__icontains=location.name).first()
|
||||
if geoloc:
|
||||
location.geo_location = geoloc
|
||||
update_fields.append("geo_location")
|
||||
@ -474,9 +466,7 @@ def email_scrobble_board_game(
|
||||
log_data.pop("expansion_ids")
|
||||
|
||||
if play_dict.get("locationRefId", False):
|
||||
log_data["location_id"] = locations[
|
||||
play_dict.get("locationRefId")
|
||||
].id
|
||||
log_data["location_id"] = locations[play_dict.get("locationRefId")].id
|
||||
if play_dict.get("rounds", False):
|
||||
log_data["rounds"] = play_dict.get("rounds")
|
||||
if play_dict.get("board", False):
|
||||
@ -499,9 +489,7 @@ def email_scrobble_board_game(
|
||||
timestamp = parse(play_dict.get("playDate"))
|
||||
if hour and minute:
|
||||
logger.info(f"Scrobble playDate has manual start time {timestamp}")
|
||||
timestamp = timestamp.replace(
|
||||
hour=hour, minute=minute, second=second or 0
|
||||
)
|
||||
timestamp = timestamp.replace(hour=hour, minute=minute, second=second or 0)
|
||||
logger.info(f"Update to {timestamp}")
|
||||
|
||||
profile = UserProfile.objects.filter(user_id=user_id).first()
|
||||
@ -596,9 +584,7 @@ def manual_scrobble_from_url(
|
||||
scrobbler. Otherwise, return nothing."""
|
||||
|
||||
if RecipeScraperService.is_recipe_url(url):
|
||||
return scrobble_from_recipe_website(
|
||||
url, user_id, source=source, action=action
|
||||
)
|
||||
return scrobble_from_recipe_website(url, user_id, source=source, action=action)
|
||||
|
||||
content_key = ""
|
||||
domain = extract_domain(url)
|
||||
@ -801,9 +787,7 @@ def emacs_scrobble_update_task(
|
||||
if not scrobble.log.get('notes"'):
|
||||
scrobble.log["notes"] = []
|
||||
if note.get("timestamp") not in existing_note_ts:
|
||||
scrobble.log["notes"].append(
|
||||
{note.get("timestamp"): note.get("content")}
|
||||
)
|
||||
scrobble.log["notes"].append({note.get("timestamp"): note.get("content")})
|
||||
notes_updated = True
|
||||
|
||||
if notes_updated:
|
||||
@ -829,9 +813,7 @@ def emacs_scrobble_task(
|
||||
user_context_list: list[str] = [],
|
||||
) -> Scrobble | None:
|
||||
orgmode_id = task_data.get("source_id")
|
||||
title = get_title_from_labels(
|
||||
task_data.get("labels", []), user_context_list
|
||||
)
|
||||
title = get_title_from_labels(task_data.get("labels", []), user_context_list)
|
||||
|
||||
task = Task.find_or_create(title)
|
||||
|
||||
@ -954,9 +936,7 @@ def manual_scrobble_webpage(
|
||||
):
|
||||
|
||||
if RecipeScraperService.is_recipe_url(url):
|
||||
return scrobble_from_recipe_website(
|
||||
url, user_id, source=source, action=action
|
||||
)
|
||||
return scrobble_from_recipe_website(url, user_id, source=source, action=action)
|
||||
|
||||
webpage = WebPage.find_or_create({"url": url})
|
||||
|
||||
|
||||
@ -155,25 +155,17 @@ class RecentScrobbleList(ListView):
|
||||
next_date = date + timedelta(weeks=+2)
|
||||
prev_date = date + timedelta(weeks=-1)
|
||||
if date.isocalendar()[1] < today.isocalendar()[1]:
|
||||
data[
|
||||
"next_link"
|
||||
] = f"?date={next_date.strftime('%Y-W%W')}"
|
||||
data["next_link"] = f"?date={next_date.strftime('%Y-W%W')}"
|
||||
data["prev_link"] = f"?date={prev_date.strftime('%Y-W%W')}"
|
||||
data[
|
||||
"title"
|
||||
] = f"Week {date.strftime('%-W')} of {date.year}"
|
||||
data["title"] = f"Week {date.strftime('%-W')} of {date.year}"
|
||||
data = data | Scrobble.as_dict_by_type(
|
||||
Scrobble.for_week(
|
||||
user_id, date.year, date.isocalendar()[1]
|
||||
)
|
||||
Scrobble.for_week(user_id, date.year, date.isocalendar()[1])
|
||||
)
|
||||
elif date_str == "this_month" or date_str.count("-") == 1:
|
||||
next_date = date + relativedelta(months=1)
|
||||
prev_date = date + relativedelta(months=-1)
|
||||
if date.month < today.month:
|
||||
data[
|
||||
"next_link"
|
||||
] = f"?date={next_date.strftime('%Y-%m')}"
|
||||
data["next_link"] = f"?date={next_date.strftime('%Y-%m')}"
|
||||
data["title"] = f"{date.strftime('%B %Y')}"
|
||||
data["prev_link"] = f"?date={prev_date.strftime('%Y-%m')}"
|
||||
data = data | Scrobble.as_dict_by_type(
|
||||
@ -182,24 +174,16 @@ class RecentScrobbleList(ListView):
|
||||
elif date_str == "today" or date_str.count("-") == 2:
|
||||
next_date = date + timedelta(days=1)
|
||||
prev_date = date - timedelta(days=1)
|
||||
data[
|
||||
"prev_link"
|
||||
] = f"?date={prev_date.strftime('%Y-%m-%d')}"
|
||||
data["prev_link"] = f"?date={prev_date.strftime('%Y-%m-%d')}"
|
||||
if date < today:
|
||||
data[
|
||||
"next_link"
|
||||
] = f"?date={next_date.strftime('%Y-%m-%d')}"
|
||||
data["next_link"] = f"?date={next_date.strftime('%Y-%m-%d')}"
|
||||
if date == today:
|
||||
data["title"] = "Today"
|
||||
else:
|
||||
data["title"] = f"{date.strftime('%Y-%m-%d')}"
|
||||
data[
|
||||
"today_link"
|
||||
] = f"?date={today.strftime('%Y-%m-%d')}"
|
||||
data["today_link"] = f"?date={today.strftime('%Y-%m-%d')}"
|
||||
data = data | Scrobble.as_dict_by_type(
|
||||
Scrobble.for_day(
|
||||
user_id, date.year, date.month, date.day
|
||||
)
|
||||
Scrobble.for_day(user_id, date.year, date.month, date.day)
|
||||
)
|
||||
elif date_str == "this_year" or date_str.count("-") == 0:
|
||||
next_date = date + relativedelta(years=+1)
|
||||
@ -222,9 +206,7 @@ class RecentScrobbleList(ListView):
|
||||
data = data | Scrobble.as_dict_by_type(
|
||||
Scrobble.for_day(user_id, date.year, date.month, date.day)
|
||||
)
|
||||
data[
|
||||
"today_link"
|
||||
] = "" # f"?date={today.strftime('%Y-%m-%d')}"
|
||||
data["today_link"] = "" # f"?date={today.strftime('%Y-%m-%d')}"
|
||||
|
||||
data["active_imports"] = AudioScrobblerTSVImport.objects.filter(
|
||||
processing_started__isnull=False,
|
||||
@ -232,7 +214,9 @@ class RecentScrobbleList(ListView):
|
||||
user=self.request.user,
|
||||
)
|
||||
data["counts"] = [] # scrobble_counts(user)
|
||||
data["daily_calories"] = get_daily_calories_for_user_by_day(self.request.user.id, date)
|
||||
data["daily_calories"] = get_daily_calories_for_user_by_day(
|
||||
self.request.user.id, date
|
||||
)
|
||||
else:
|
||||
data["weekly_data"] = week_of_scrobbles()
|
||||
data["counts"] = scrobble_counts()
|
||||
@ -251,9 +235,7 @@ class ScrobbleLongPlaysView(TemplateView):
|
||||
def get_context_data(self, **kwargs):
|
||||
context_data = super().get_context_data(**kwargs)
|
||||
context_data["view"] = self.request.GET.get("view", "grid")
|
||||
context_data["in_progress"] = get_long_plays_in_progress(
|
||||
self.request.user
|
||||
)
|
||||
context_data["in_progress"] = get_long_plays_in_progress(self.request.user)
|
||||
context_data["completed"] = get_long_plays_completed(self.request.user)
|
||||
return context_data
|
||||
|
||||
@ -330,9 +312,7 @@ class ManualScrobbleView(FormView):
|
||||
scrobble_fn = MANUAL_SCROBBLE_FNS[key]
|
||||
scrobble = eval(scrobble_fn)(item_id, self.request.user.id)
|
||||
|
||||
return HttpResponseRedirect(
|
||||
scrobble.redirect_url(self.request.user.id)
|
||||
)
|
||||
return HttpResponseRedirect(scrobble.redirect_url(self.request.user.id))
|
||||
|
||||
|
||||
class JsonableResponseMixin:
|
||||
@ -378,9 +358,7 @@ class AudioScrobblerImportCreateView(
|
||||
return HttpResponseRedirect(self.request.META.get("HTTP_REFERER"))
|
||||
|
||||
|
||||
class KoReaderImportCreateView(
|
||||
LoginRequiredMixin, JsonableResponseMixin, CreateView
|
||||
):
|
||||
class KoReaderImportCreateView(LoginRequiredMixin, JsonableResponseMixin, CreateView):
|
||||
model = KoReaderImport
|
||||
fields = ["sqlite_file"]
|
||||
template_name = "scrobbles/upload_form.html"
|
||||
@ -439,9 +417,7 @@ def web_scrobbler_webhook(request):
|
||||
playing_state = "started"
|
||||
if request.POST.get("isPlaying") == "false":
|
||||
playing_state = "stopped"
|
||||
scrobble = web_scrobbler_scrobble_media(
|
||||
youtube_id, user_id, status=playing_state
|
||||
)
|
||||
scrobble = web_scrobbler_scrobble_media(youtube_id, user_id, status=playing_state)
|
||||
if not scrobble:
|
||||
logger.warning(
|
||||
"[web_scrobbler_webhook] failed",
|
||||
@ -566,18 +542,12 @@ def import_audioscrobbler_file(request):
|
||||
scrobbles_created = []
|
||||
# tsv_file = request.FILES[0]
|
||||
|
||||
file_serializer = serializers.AudioScrobblerTSVImportSerializer(
|
||||
data=request.data
|
||||
)
|
||||
file_serializer = serializers.AudioScrobblerTSVImportSerializer(data=request.data)
|
||||
if file_serializer.is_valid():
|
||||
import_file = file_serializer.save()
|
||||
return Response(
|
||||
{"scrobble_ids": scrobbles_created}, status=status.HTTP_200_OK
|
||||
)
|
||||
return Response({"scrobble_ids": scrobbles_created}, status=status.HTTP_200_OK)
|
||||
else:
|
||||
return Response(
|
||||
file_serializer.errors, status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
@permission_classes([IsAuthenticated])
|
||||
@ -623,9 +593,9 @@ def scrobble_start(request, uuid):
|
||||
request, messages.ERROR, f"Media with uuid {uuid} not found."
|
||||
)
|
||||
|
||||
if (
|
||||
user.profile.redirect_to_webpage
|
||||
and (media_obj.__class__.__name__ == Scrobble.MediaType.WEBPAGE or media_obj.__class__.__name__ == Scrobble.MediaType.BOOK)
|
||||
if user.profile.redirect_to_webpage and (
|
||||
media_obj.__class__.__name__ == Scrobble.MediaType.WEBPAGE
|
||||
or media_obj.__class__.__name__ == Scrobble.MediaType.BOOK
|
||||
):
|
||||
logger.info(f"Redirecting to {media_obj} detail page")
|
||||
return HttpResponseRedirect(media_obj.url)
|
||||
@ -754,9 +724,7 @@ class ChartRecordView(TemplateView):
|
||||
).order_by("rank")
|
||||
|
||||
if charts.count() == 0:
|
||||
ChartRecord.build(
|
||||
user=self.request.user, model_str=media_type, **kwargs
|
||||
)
|
||||
ChartRecord.build(user=self.request.user, model_str=media_type, **kwargs)
|
||||
charts = ChartRecord.objects.filter(
|
||||
media_filter, user=self.request.user, **kwargs
|
||||
).order_by("rank")
|
||||
@ -788,9 +756,7 @@ class ChartRecordView(TemplateView):
|
||||
media_type = self.request.GET.get("media", "Track")
|
||||
user = self.request.user
|
||||
params = {}
|
||||
context_data["chart_type"] = self.request.GET.get(
|
||||
"chart_type", "maloja"
|
||||
)
|
||||
context_data["chart_type"] = self.request.GET.get("chart_type", "maloja")
|
||||
context_data["artist_charts"] = {}
|
||||
|
||||
if not date:
|
||||
@ -855,9 +821,7 @@ class ChartRecordView(TemplateView):
|
||||
params["day"] = day
|
||||
month_str = calendar.month_name[month]
|
||||
name = f"Chart for {month_str} {day}, {year}"
|
||||
in_progress = (
|
||||
now.month == month and now.year == year and now.day == day
|
||||
)
|
||||
in_progress = now.month == month and now.year == year and now.day == day
|
||||
|
||||
media_filter = self.get_media_filter("Track")
|
||||
track_charts = ChartRecord.objects.filter(
|
||||
@ -869,17 +833,13 @@ class ChartRecordView(TemplateView):
|
||||
).order_by("rank")
|
||||
|
||||
if track_charts.count() == 0 and not in_progress:
|
||||
ChartRecord.build(
|
||||
user=self.request.user, model_str="Track", **params
|
||||
)
|
||||
ChartRecord.build(user=self.request.user, model_str="Track", **params)
|
||||
media_filter = self.get_media_filter("Track")
|
||||
track_charts = ChartRecord.objects.filter(
|
||||
media_filter, user=self.request.user, **params
|
||||
).order_by("rank")
|
||||
if artist_charts.count() == 0 and not in_progress:
|
||||
ChartRecord.build(
|
||||
user=self.request.user, model_str="Artist", **params
|
||||
)
|
||||
ChartRecord.build(user=self.request.user, model_str="Artist", **params)
|
||||
media_filter = self.get_media_filter("Artist")
|
||||
artist_charts = ChartRecord.objects.filter(
|
||||
media_filter, user=self.request.user, **params
|
||||
@ -900,38 +860,24 @@ class ScrobbleStatusView(LoginRequiredMixin, TemplateView):
|
||||
def get_context_data(self, **kwargs):
|
||||
data = super().get_context_data(**kwargs)
|
||||
user_scrobble_qs = Scrobble.objects.filter().order_by("-timestamp")
|
||||
progress_plays = user_scrobble_qs.filter(
|
||||
in_progress=True, is_paused=False
|
||||
)
|
||||
progress_plays = user_scrobble_qs.filter(in_progress=True, is_paused=False)
|
||||
|
||||
data["listening"] = progress_plays.filter(
|
||||
Q(track__isnull=False) | Q(podcast_episode__isnull=False)
|
||||
).first()
|
||||
data["watching"] = progress_plays.filter(video__isnull=False).first()
|
||||
data["going"] = progress_plays.filter(
|
||||
geo_location__isnull=False
|
||||
).first()
|
||||
data["playing"] = progress_plays.filter(
|
||||
board_game__isnull=False
|
||||
).first()
|
||||
data["sporting"] = progress_plays.filter(
|
||||
sport_event__isnull=False
|
||||
).first()
|
||||
data["browsing"] = progress_plays.filter(
|
||||
web_page__isnull=False
|
||||
).first()
|
||||
data["participating"] = progress_plays.filter(
|
||||
life_event__isnull=False
|
||||
).first()
|
||||
data["going"] = progress_plays.filter(geo_location__isnull=False).first()
|
||||
data["playing"] = progress_plays.filter(board_game__isnull=False).first()
|
||||
data["sporting"] = progress_plays.filter(sport_event__isnull=False).first()
|
||||
data["browsing"] = progress_plays.filter(web_page__isnull=False).first()
|
||||
data["participating"] = progress_plays.filter(life_event__isnull=False).first()
|
||||
data["working"] = progress_plays.filter(task__isnull=False).first()
|
||||
|
||||
long_plays = user_scrobble_qs.filter(
|
||||
long_play_complete=False, played_to_completion=True
|
||||
)
|
||||
data["reading"] = long_plays.filter(book__isnull=False).first()
|
||||
data["sessioning"] = long_plays.filter(
|
||||
video_game__isnull=False
|
||||
).first()
|
||||
data["sessioning"] = long_plays.filter(video_game__isnull=False).first()
|
||||
|
||||
return data
|
||||
|
||||
@ -949,14 +895,16 @@ class ScrobbleDetailView(DetailView):
|
||||
|
||||
log = self.object.log or {}
|
||||
initial_notes = log.get("notes", [])
|
||||
if isinstance(initial_notes, list) and len(initial_notes) > 0 and isinstance(initial_notes[0], dict):
|
||||
if (
|
||||
isinstance(initial_notes, list)
|
||||
and len(initial_notes) > 0
|
||||
and isinstance(initial_notes[0], dict)
|
||||
):
|
||||
notes_str = note_list_to_str(notes)
|
||||
else:
|
||||
notes_str = "\n".join(initial_notes) if initial_notes else ""
|
||||
|
||||
notes_str_fixed = notes_str.encode("utf-8").decode(
|
||||
"unicode_escape"
|
||||
)
|
||||
notes_str_fixed = notes_str.encode("utf-8").decode("unicode_escape")
|
||||
log["notes"] = notes_str_fixed
|
||||
|
||||
return FormClass(initial=log)
|
||||
@ -975,9 +923,7 @@ class ScrobbleDetailView(DetailView):
|
||||
data[field_name] = original_value
|
||||
|
||||
if data.get("with_people_ids", False):
|
||||
data["with_people_ids"] = [
|
||||
p.id for p in data["with_people_ids"]
|
||||
]
|
||||
data["with_people_ids"] = [p.id for p in data["with_people_ids"]]
|
||||
|
||||
if data.get("platform_id", False):
|
||||
data["platform_id"] = data["platform_id"].id
|
||||
|
||||
@ -37,9 +37,7 @@ TESTING = len(sys.argv) > 1 and sys.argv[1] == "test"
|
||||
|
||||
TAGGIT_CASE_INSENSITIVE = True
|
||||
|
||||
KEEP_DETAILED_SCROBBLE_LOGS = os.getenv(
|
||||
"VROBBLER_KEEP_DETAILED_SCROBBLE_LOGS", False
|
||||
)
|
||||
KEEP_DETAILED_SCROBBLE_LOGS = os.getenv("VROBBLER_KEEP_DETAILED_SCROBBLE_LOGS", False)
|
||||
|
||||
# Key must be 16, 24 or 32 bytes long and will be converted to a byte stream
|
||||
ENCRYPTED_FIELD_KEY = os.getenv(
|
||||
@ -54,9 +52,7 @@ DELETE_STALE_SCROBBLES = (
|
||||
)
|
||||
|
||||
# Used to dump data coming from srobbling sources, helpful for building new inputs
|
||||
DUMP_REQUEST_DATA = (
|
||||
os.getenv("VROBBLER_DUMP_REQUEST_DATA", "false").lower() in TRUTHY
|
||||
)
|
||||
DUMP_REQUEST_DATA = os.getenv("VROBBLER_DUMP_REQUEST_DATA", "false").lower() in TRUTHY
|
||||
|
||||
USDA_API_KEY = os.getenv("VROBBLER_USDA_API_KEY")
|
||||
THESPORTSDB_API_KEY = os.getenv("VROBBLER_THESPORTSDB_API_KEY", "2")
|
||||
@ -72,9 +68,7 @@ COMICVINE_API_KEY = os.getenv("VROBBLER_COMICVINE_API_KEY")
|
||||
BGG_ACCESS_TOKEN = os.getenv("VROBBLER_BGG_ACCESS_TOKEN", "")
|
||||
GEOLOC_ACCURACY = os.getenv("VROBBLER_GEOLOC_ACCURACY", 3)
|
||||
GEOLOC_PROXIMITY = os.getenv("VROBBLER_GEOLOC_PROXIMITY", "0.0001")
|
||||
POINTS_FOR_MOVEMENT_HISTORY = os.getenv(
|
||||
"VROBBLER_POINTS_FOR_MOVEMENT_HISTORY", 3
|
||||
)
|
||||
POINTS_FOR_MOVEMENT_HISTORY = os.getenv("VROBBLER_POINTS_FOR_MOVEMENT_HISTORY", 3)
|
||||
TODOIST_CLIENT_ID = os.getenv("VROBBLER_TODOIST_CLIENT_ID", "")
|
||||
TODOIST_CLIENT_SECRET = os.getenv("VROBBLER_TODOIST_CLIENT_SECRET", "")
|
||||
|
||||
@ -97,9 +91,7 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
||||
TIME_ZONE = os.getenv("VROBBLER_TIME_ZONE", "America/New_York")
|
||||
|
||||
ALLOWED_HOSTS = ["*"]
|
||||
CSRF_TRUSTED_ORIGINS = [
|
||||
os.getenv("VROBBLER_TRUSTED_ORIGINS", "http://localhost:8000")
|
||||
]
|
||||
CSRF_TRUSTED_ORIGINS = [os.getenv("VROBBLER_TRUSTED_ORIGINS", "http://localhost:8000")]
|
||||
X_FRAME_OPTIONS = "SAMEORIGIN"
|
||||
|
||||
REDIS_URL = os.getenv("VROBBLER_REDIS_URL", None)
|
||||
@ -108,9 +100,7 @@ if REDIS_URL:
|
||||
else:
|
||||
print("Eagerly running all tasks")
|
||||
|
||||
CELERY_TASK_ALWAYS_EAGER = (
|
||||
os.getenv("VROBBLER_SKIP_CELERY", "false").lower() in TRUTHY
|
||||
)
|
||||
CELERY_TASK_ALWAYS_EAGER = os.getenv("VROBBLER_SKIP_CELERY", "false").lower() in TRUTHY
|
||||
CELERY_BROKER_URL = REDIS_URL if REDIS_URL else "memory://localhost/"
|
||||
CELERY_RESULT_BACKEND = "django-db"
|
||||
CELERY_TIMEZONE = os.getenv("VROBBLER_TIME_ZONE", "America/New_York")
|
||||
@ -210,9 +200,7 @@ DATABASES = {
|
||||
}
|
||||
|
||||
if TESTING:
|
||||
DATABASES = {
|
||||
"default": dj_database_url.config(default="sqlite:///testdb.sqlite3")
|
||||
}
|
||||
DATABASES = {"default": dj_database_url.config(default="sqlite:///testdb.sqlite3")}
|
||||
|
||||
db_str = ""
|
||||
if "sqlite" in DATABASES["default"]["ENGINE"]:
|
||||
@ -310,9 +298,7 @@ else:
|
||||
STATIC_ROOT = os.getenv(
|
||||
"VROBBLER_STATIC_ROOT", os.path.join(PROJECT_ROOT, "static")
|
||||
)
|
||||
MEDIA_ROOT = os.getenv(
|
||||
"VROBBLER_MEDIA_ROOT", os.path.join(PROJECT_ROOT, "media")
|
||||
)
|
||||
MEDIA_ROOT = os.getenv("VROBBLER_MEDIA_ROOT", os.path.join(PROJECT_ROOT, "media"))
|
||||
STATIC_URL = os.getenv("VROBBLER_STATIC_URL", "/static/")
|
||||
MEDIA_URL = os.getenv("VROBBLER_MEDIA_URL", "/media/")
|
||||
|
||||
@ -396,9 +382,7 @@ LOGGING = {
|
||||
},
|
||||
}
|
||||
|
||||
LOG_TO_CONSOLE = (
|
||||
os.getenv("VROBBLER_LOG_TO_CONSOLE", "false").lower() in TRUTHY
|
||||
)
|
||||
LOG_TO_CONSOLE = os.getenv("VROBBLER_LOG_TO_CONSOLE", "false").lower() in TRUTHY
|
||||
if LOG_TO_CONSOLE:
|
||||
LOGGING["loggers"]["django"]["handlers"] = ["console"]
|
||||
LOGGING["loggers"]["vrobbler"]["handlers"] = ["console"]
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
from oauth2_provider import urls as oauth2_urls
|
||||
@ -6,7 +8,12 @@ from rest_framework import routers
|
||||
import vrobbler.apps.scrobbles.views as scrobbles_views
|
||||
|
||||
from vrobbler.apps.boardgames import urls as boardgame_urls
|
||||
from vrobbler.apps.boardgames.api.views import BoardGameViewSet, BoardGameDesignerViewSet, BoardGamePublisherViewSet, BoardGameLocationViewSet
|
||||
from vrobbler.apps.boardgames.api.views import (
|
||||
BoardGameViewSet,
|
||||
BoardGameDesignerViewSet,
|
||||
BoardGamePublisherViewSet,
|
||||
BoardGameLocationViewSet,
|
||||
)
|
||||
|
||||
from vrobbler.apps.books import urls as book_urls
|
||||
from vrobbler.apps.books.api.views import AuthorViewSet, BookViewSet
|
||||
@ -31,7 +38,11 @@ from vrobbler.apps.music.api.views import (
|
||||
)
|
||||
|
||||
from vrobbler.apps.podcasts import urls as podcast_urls
|
||||
from vrobbler.apps.podcasts.api.views import ProducerViewSet, PodcastViewSet, PodcastEpisodeViewSet
|
||||
from vrobbler.apps.podcasts.api.views import (
|
||||
ProducerViewSet,
|
||||
PodcastViewSet,
|
||||
PodcastEpisodeViewSet,
|
||||
)
|
||||
|
||||
from vrobbler.apps.scrobbles import urls as scrobble_urls
|
||||
from vrobbler.apps.scrobbles.api.views import (
|
||||
@ -60,14 +71,25 @@ from vrobbler.apps.trails import urls as trails_urls
|
||||
from vrobbler.apps.trails.api.views import TrailViewSet
|
||||
|
||||
from vrobbler.apps.beers import urls as beers_urls
|
||||
from vrobbler.apps.beers.api.views import BeerViewSet, BeerProducerViewSet, BeerStyleViewSet
|
||||
from vrobbler.apps.beers.api.views import (
|
||||
BeerViewSet,
|
||||
BeerProducerViewSet,
|
||||
BeerStyleViewSet,
|
||||
)
|
||||
|
||||
from vrobbler.apps.puzzles import urls as puzzles_urls
|
||||
from vrobbler.apps.puzzles.api.views import PuzzleViewSet, PuzzleManufacturerViewSet
|
||||
from vrobbler.apps.puzzles.api.views import (
|
||||
PuzzleViewSet,
|
||||
PuzzleManufacturerViewSet,
|
||||
)
|
||||
from vrobbler.apps.videogames import urls as videogame_urls
|
||||
|
||||
from vrobbler.apps.videos import urls as video_urls
|
||||
from vrobbler.apps.videos.api.views import ChannelViewSet, SeriesViewSet, VideoViewSet
|
||||
from vrobbler.apps.videos.api.views import (
|
||||
ChannelViewSet,
|
||||
SeriesViewSet,
|
||||
VideoViewSet,
|
||||
)
|
||||
|
||||
from vrobbler.apps.bricksets import urls as bricksets_urls
|
||||
from vrobbler.apps.bricksets.api.views import BrickSetViewSet
|
||||
@ -149,3 +171,10 @@ urlpatterns = [
|
||||
"", scrobbles_views.RecentScrobbleList.as_view(), name="vrobbler-home"
|
||||
),
|
||||
]
|
||||
if settings.DEBUG:
|
||||
urlpatterns = urlpatterns + static(
|
||||
settings.STATIC_URL, document_root=settings.STATIC_ROOT
|
||||
)
|
||||
urlpatterns = urlpatterns + static(
|
||||
settings.MEDIA_URL, document_root=settings.MEDIA_ROOT
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user