3

I have .memo files on my PC from the default memo app on a previously owned Samsung phone. When opened in Notepad, the files do not contain plain text. How can I recover the contents of the memos?

4 Answers 4

2

By using VLC player or downloading Samsung Note for PC as mentioned here

Related methods mentioned here for export - see Husni's answer of zip file solution and others

How can I export Samsung memos?

0
3

I wrote my own "memo2txt" converter in Python. Here is the script (first you'll need to install Python libs using pip):

import os
import re
import glob
import zipfile
import xmltodict
from datetime import datetime

MEMO_PATH = r'i:\MY\PROGRAMMING\AndroidMemoExtracter\MemoFiles'
RESULTS_PATH = r'i:\MY\PROGRAMMING\AndroidMemoExtracter\Results'

memos = glob.glob(MEMO_PATH + '\*.memo')

for i, memo in enumerate(memos):
    print('{}/{} - {}'.format(i+1, len(memos), memo))

    try:
        # Extract *.memo file and read the content
        archive = zipfile.ZipFile(memo, 'r')
        memo_content = archive.read('memo_content.xml').decode('utf-8')
        cleanr = re.compile('&.*?;')
        memo_content = re.sub(cleanr, '', memo_content)
        memo_content = xmltodict.parse(memo_content)
        text = memo_content['memo']['contents']['content']

        # Generate filename from memo timestamp
        timestamp = int(memo_content['memo']['header']['meta'][2]['@createdTime'][:10])
        date = datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H-%M-%S')
        file_name = '{}.txt'.format(date)

        # Save file as a *.txt
        with open(os.path.join(RESULTS_PATH, file_name), 'w', encoding='utf-8') as file:
            file.write(text)

    except zipfile.BadZipFile:
        continue
2

inspired by beeshyams, here's my version ...

on my Samsung J3, the memos are in an MTP drive somwhere like ...

SAMSUNG Android/Phone/ShareMemo/*.memo

the source xml looks something like this:

<?xml version="1.0" encoding="UTF-8"?>
<memo Version="1.0">
<header>
<meta title="==PROGRAMMING=="/>
<meta favourite="false"/>
<meta uuid="85f94ab2-77a8-XXXXXXXXXXXXXXX"/>
<meta createdTime="1551038092051"/>
</header>
<contents>
<content>&lt;p value="memo2" &gt;=====&lt;/p&gt;&lt;p&gt;https://medium.freecodecamp.org/&lt;/p&gt;&lt;p&gt;=====&lt;/p&gt;
</content>
</contents>
</memo>

I run this xslt transform over it ...

 <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

     <xsl:variable name="s1">
      <!--  https://float-middle.com/how-to-put-cdata-into-script-tag-in-xslt/  -->
      <![CDATA[
       //https://stackoverflow.com/questions/847185/convert-a-unix-timestamp-to-time-in-javascript
       //https://stackoverflow.com/questions/5292372/how-to-pass-parameters-to-a-script-tag
       var ts = document.currentScript.getAttribute('timestamp')
       document.write(""+ts+":   "+Date(ts).toLocaleString());
     ]]>
     </xsl:variable>

     <xsl:template match="/">
       <html lang="en_UK">
          <head>
           <style>
            body {background-color: powderblue;}
            #title {color: red; font-size: 300%;}
            .content {color: green;}
          </style>
          <meta charset="UTF-8"/>
           <title>
            <xsl:apply-templates select="memo/header/meta[@title]"/>
           </title>
         </head>
         <body>

          <span id='title'>
           <xsl:apply-templates select="memo/header/meta[@title]"/>
          </span>

          <xsl:text disable-output-escaping="yes">
           <![CDATA[&nbsp;&mdash;&nbsp;]]>
          </xsl:text>

          <span id='created'>
           <xsl:apply-templates select="memo/header/meta[@createdTime]"/>
          </span>

          <div class='content'>
           <xsl:apply-templates select="memo/contents"/>
          </div>

         </body>
       </html>
     </xsl:template>

     <!-- ============================================ -->

     <xsl:template match="memo/header/meta[@title]">
      <xsl:apply-templates select="@title"/>
     </xsl:template>

     <xsl:template match="@title">
      <xsl:value-of select="."/>
      <xsl:if test="string-length(.)=0">...</xsl:if>
     </xsl:template>

     <!-- ============================================ -->

     <xsl:template match="memo/header/meta[@createdTime]">
      <script type="text/javascript">
       <xsl:attribute name="timestamp">
        <xsl:value-of select="@createdTime" />
       </xsl:attribute>

       <!--  https://float-middle.com/how-to-put-cdata-into-script-tag-in-xslt/ -->
       <xsl:text disable-output-escaping="yes">
        /* &lt;![CDATA[ */
       </xsl:text>
         <xsl:value-of select="$s1" disable-output-escaping="yes"/>
       <xsl:text disable-output-escaping="yes">
        /* ]]&gt; */
       </xsl:text>
      </script>
     </xsl:template>

     <xsl:template match="@createdTime">
      <xsl:value-of select="."/>
     </xsl:template>

     <!-- ============================================ -->

     <xsl:template match="memo/contents">
      <xsl:value-of select="content" disable-output-escaping="yes"/>
      <xsl:if test="string-length(content)=0">...</xsl:if>
     </xsl:template>

 </xsl:stylesheet>

using lxml from python..

import os
import glob
import zipfile
from lxml import etree

import sys

if len(sys.argv) < 3:
    print('python3 convert_memos.py <memo-dir>  <html-dir>')
    sys.exit()

MEMO_PATH = os.path.join(sys.argv[1], '')
HTML_PATH = os.path.join(sys.argv[2], '')

xslt_src = '''[see xml above]'''


memos = glob.glob(MEMO_PATH + '*.memo')

for i, memo in enumerate(memos):

    try:

        archive = zipfile.ZipFile(memo, 'r')
        src = archive.read('memo_content.xml').decode('utf-8')

        xslt = etree.XML(xslt_src)
        xml = etree.XML(str.encode(src))
        transform = etree.XSLT(xslt)
        result = transform(xml)
        root = result.getroot()

        html = etree.tostring(root, pretty_print=True).decode('utf-8')

        filename = '{}.html'.format(os.path.basename(memo))
        filename = os.path.join(HTML_PATH, filename)

        with open(filename, 'w', encoding='utf-8') as file:
            file.write('<!DOCTYPE html>')
            file.write(html)

    except Exception as e:
        print(e)


outputs something like ..

<!DOCTYPE html>
<html lang="en_UK">
  <head>
    <style>
            body {background-color: powderblue;}
            #title {color: red; font-size: 300%;}
            .content {color: green;}
          </style>
    <meta charset="UTF-8"/>
    <title>==PROGRAMMING==</title>
  </head>
  <body>
   <span id="title">
        ==PROGRAMMING==
   </span>
   &nbsp;&mdash;&nbsp;
   <span id="created">
    <script type="text/javascript" timestamp="1551038092051">
     /* <![CDATA[ */
      var ts = document.currentScript.getAttribute('timestamp')
      document.write(""+ts+":   "+Date(ts).toLocaleString());
     /* ]]> */
    </script>
   </span>
   <div class="content">
       <p value="memo2" >=====</p>
       <p>https://medium.freecodecamp.org/</p>
       <p>=====</p>
   </div>
 </body>
</html>
2

I am forking @Alderven 's version to import the media files, and convert the emojis to proper UTF-8 characters. That way they are easy to import to Notable (on the Linux desktop) and sync back to Markor (on android). I posted this on my Github https://github.com/morciej/memo2html -- feel free to use.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .