[PubSub] remove now unused code to complete migration
[mygpo.git] / mygpo / maintenance / migrate.py
blob6f5fb3d7c68bbb23a3ecbd023255318b9e336078
1 from __future__ import unicode_literals
3 import json
4 from datetime import datetime
6 from django.contrib.contenttypes.models import ContentType
7 from django.contrib.auth.models import User
9 from mygpo.podcasts.models import Tag
10 from mygpo.users.models import Chapter as C, EpisodeUserState, Client
11 from mygpo.chapters.models import Chapter
12 from mygpo.subscriptions.models import Subscription, PodcastConfig
13 from mygpo.history.models import EpisodeHistoryEntry
14 from mygpo.podcasts.models import Episode, Podcast
15 from mygpo.favorites.models import FavoriteEpisode
17 import logging
18 logger = logging.getLogger(__name__)
21 def to_maxlength(cls, field, val):
22 """ Cut val to the maximum length of cls's field """
23 max_length = cls._meta.get_field(field).max_length
24 orig_length = len(val)
25 if orig_length > max_length:
26 val = val[:max_length]
27 logger.warn('%s.%s length reduced from %d to %d',
28 cls.__name__, field, orig_length, max_length)
30 return val
33 #class EpisodeUserState(Document, SettingsMixin):
34 # ref_url = StringProperty(required=True)
35 # podcast_ref_url = StringProperty(required=True)
38 def migrate_estate(state):
39 """ migrate a podcast state """
41 try:
42 user = User.objects.get(profile__uuid=state.user)
43 except User.DoesNotExist:
44 logger.warn("User with ID '{id}' does not exist".format(
45 id=state.user))
46 return
48 try:
49 podcast = Podcast.objects.all().get_by_any_id(state.podcast)
50 except Podcast.DoesNotExist:
51 logger.warn("Podcast with ID '{id}' does not exist".format(
52 id=state.podcast))
53 return
55 try:
56 episode = Episode.objects.filter(podcast=podcast).get_by_any_id(state.episode)
57 except Episode.DoesNotExist:
58 logger.warn("Episode with ID '{id}' does not exist".format(
59 id=state.episode))
60 return
62 logger.info('Migrating episode state ({id}) for user {user} and episode {episode}'
63 .format(id=state._id, user=user, episode=episode))
65 for chapter in state.chapters:
66 migrate_chapter(user, episode, chapter)
68 for action in state.actions:
69 migrate_eaction(user, episode, state, action)
71 is_favorite = state.settings.get('is_favorite', False)
72 if is_favorite:
73 logger.info('Favorite episode')
74 FavoriteEpisode.objects.get_or_create(user=user, episode=episode)
75 else:
76 FavoriteEpisode.objects.filter(user=user, episode=episode).delete()
79 def migrate_chapter(user, episode, c):
81 chapter, created = Chapter.objects.get_or_create(
82 user=user,
83 episode=episode,
84 start=c.start,
85 end=c.end,
86 defaults = {
87 'label': c.label or '',
88 'advertisement': c.advertisement,
93 def migrate_eaction(user, episode, state, ea):
95 logger.info('Migrating {action} action'.format(action=ea.action))
97 if ea.device is None:
98 client = None
100 else:
101 try:
102 client = user.client_set.get(id=ea.device)
103 except Client.DoesNotExist:
104 logger.warn("Client '{cid}' does not exist; skipping".format(
105 cid=ea.device))
106 return
108 created = datetime.utcfromtimestamp(ea.upload_timestamp) if ea.upload_timestamp else datetime.utcnow()
109 entry, created = EpisodeHistoryEntry.objects.get_or_create(
110 user=user,
111 client=client,
112 episode=episode,
113 action=ea.action,
114 timestamp=ea.timestamp,
115 defaults = {
116 'created': created,
117 'started': ea.started,
118 'stopped': ea.playmark,
119 'total': ea.total,
120 'podcast_ref_url': state.podcast_ref_url,
121 'episode_ref_url': state.ref_url,
125 if created:
126 logger.info('Episode History Entry created: {user} {action} {episode}'
127 'on {client} @ {timestamp}'.format(user=user,
128 action=entry.action, episode=episode, client=client,
129 timestamp=entry.timestamp))
132 def get_subscribed_devices(state):
133 """ device Ids on which the user subscribed to the podcast """
134 devices = {}
136 for action in state.actions:
137 if action.action == "subscribe":
138 if not action.device in state.disabled_devices:
139 devices[action.device] = action.timestamp
140 else:
141 if action.device in devices:
142 devices.pop(action.device)
144 return devices
148 from couchdbkit import Database
149 db = Database('http://127.0.0.1:5984/mygpo_userdata_copy')
150 from couchdbkit.changes import ChangesStream, fold, foreach
153 MIGRATIONS = {
154 'PodcastUserState': (None, None),
155 'User': (None, None),
156 'Suggestions': (None, None),
157 'EpisodeUserState': (EpisodeUserState, migrate_estate),
160 def migrate_change(c):
161 logger.info('Migrate seq %s', c['seq'])
162 doc = c['doc']
164 if not 'doc_type' in doc:
165 logger.warn('Document contains no doc_type: %r', doc)
166 return
168 doctype = doc['doc_type']
170 cls, migrate = MIGRATIONS[doctype]
172 if cls is None:
173 logger.warn("Skipping '%s'", doctype)
174 return
176 obj = cls.wrap(doc)
177 migrate(obj)
180 def migrate(since=0, db=db):
181 with ChangesStream(db,
182 feed="continuous",
183 heartbeat=True,
184 include_docs=True,
185 since=since,
186 ) as stream:
187 for change in stream:
188 migrate_change(change)